Permalink
Browse files

Add Const functor and const function

`const` function inspired by Runar's
[A Proper Constant Function in Scala](http://apocalisp.wordpress.com/2010/04/21/a-proper-constant-function-in-scala/)
blog post.
  • Loading branch information...
1 parent 5cba367 commit d8813ebfa07712331250230f4783a60a27d9ab10 @adelbertc adelbertc committed Feb 28, 2014
@@ -0,0 +1,35 @@
+package scalaz
+
+import Id._
+
+case class Const[A, B](getConst: A) {
+ def ===(x: Const[A, B])(implicit A: Equal[A]): Boolean =
+ A.equal(getConst, x.getConst)
+
+ def map[C](f: B => C): Const[A, C] = Const(getConst)
+}
+
+object Const extends ConstInstances with ConstFunctions
+
+sealed abstract class ConstInstances {
+ /** The constant functor that maps every type to `A` */
+ implicit def constFunctor[C]: Functor[({type l[a] = Const[C, a]})#l] =
+ new Functor[({type l[a] = Const[C, a]})#l] {
+ override def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] =
+ fa.map(f)
+ }
+
+ implicit def constEqual[A : Equal, B]: Equal[Const[A, B]] =
+ new Equal[Const[A, B]] {
+ override def equal(a1: Const[A, B], a2: Const[A, B]): Boolean =
+ a1 === a2
+ }
+}
+
+trait ConstFunctions {
+ /** A properly universally quantified constant function. */
+ def const[A](a: A): Id ~> ({type l[_] = A})#l =
+ new (Id ~> ({type l[_] = A})#l) {
+ override def apply[B](fa: B): A = a
+ }
+}
@@ -241,6 +241,9 @@ object ScalazArbitrary {
implicit def eitherTArb[F[+_], A, B](implicit A: Arbitrary[F[A \/ B]]): Arbitrary[EitherT[F, A, B]] =
Functor[Arbitrary].map(A)(EitherT[F, A, B](_))
+ implicit def constArbitrary[A, B](implicit A: Arbitrary[A]): Arbitrary[Const[A, B]] =
+ Functor[Arbitrary].map(A)(Const(_))
+
implicit def dlistArbitrary[A](implicit A: Arbitrary[List[A]]) = Functor[Arbitrary].map(A)(as => DList(as : _*))
implicit def ilistArbitrary[A](implicit A: Arbitrary[List[A]]) = Functor[Arbitrary].map(A)(IList.fromList)
@@ -0,0 +1,18 @@
+package scalaz
+
+import std.AllInstances._
+import scalaz.scalacheck.ScalazProperties._
+import scalaz.scalacheck.ScalazArbitrary._
+import Const._
+import org.scalacheck.Prop.forAll
+
+object ConstTest extends SpecLite {
+ checkAll(functor.laws[({type l[a] = Const[Int, a]})#l])
+ checkAll(equal.laws[Const[Int, String]])
+
+ "const functions" in {
+ "const" ! forAll { (x: Int, y: String) =>
+ const(x)(y) == x
+ }
+ }
+}

0 comments on commit d8813eb

Please sign in to comment.