-
-
Save ahoy-jon/5899968 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Point { | |
trait PointAdder[P1, P2] { | |
def add(p1: P1, p2: P2): Point3D | |
} | |
case class Point2D(x: Int, y: Int) | |
case class Point3D(x: Int, y: Int, z: Int) | |
implicit object Point2DAdder extends PointAdder[Point2D, Point2D] { | |
def add(p1: Point2D, p2: Point2D): Point3D = Point3D(p1.x + p2.x, p1.y + p2.y, 0) | |
} | |
implicit object Point3DAdder extends PointAdder[Point3D, Point3D] { | |
def add(p1: Point3D, p2: Point3D): Point3D = Point3D(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z) | |
} | |
implicit object Point2DPoint3DAdder extends PointAdder[Point2D, Point3D] { | |
def add(p1: Point2D, p2: Point3D): Point3D = Point3D(p1.x + p2.x, p1.y + p2.y, p2.z) | |
} | |
implicit object Point3DPoint2DAdder extends PointAdder[Point3D, Point2D] { | |
def add(p1: Point3D, p2: Point2D): Point3D = Point3D(p1.x + p2.x, p1.y + p2.y, p1.z) | |
} | |
def main(args: Array[String]) { | |
val point1 = Point2D(1, 2) | |
val point2 = Point3D(1, 2, 3) | |
println(implicitly[PointAdder[Point2D, Point3D]].add(point1, point2)) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shapeless._ | |
object MonoidExamples extends App { | |
import MonoidSyntax._ | |
case class Point2D(x: Int, y: Int, labels:Set[String]) | |
case class Point3D(x: Int, y: Int, z: Int, labels:Set[String]) | |
object Point2D { | |
implicit def toPoint3D(p:Point2D):Point3D = Point3D(p.x,p.y,0, p.labels) | |
} | |
val a = Point2D(1,2, Set("ahoy")) | |
val b = Point3D(1,2,3, Set("plouf")) | |
implicit val point2DMonoid = TypeClass[Monoid,Point2D] | |
implicit val point3DMonoid = TypeClass[Monoid,Point3D] | |
println(a |+| a) | |
println(b |+| b) | |
println(b |+| a) | |
} | |
/** | |
* Pedagogic subset of the Scalaz monoid | |
*/ | |
trait Monoid[T] { | |
def zero : T | |
def append(a : T, b : T) : T | |
} | |
object Monoid extends TypeClassCompanion[Monoid] { | |
def mzero[T](implicit mt : Monoid[T]) = mt.zero | |
implicit def booleanMonoid : Monoid[Boolean] = new Monoid[Boolean] { | |
def zero = false | |
def append(a : Boolean, b : Boolean) = a || b | |
} | |
implicit def intMonoid : Monoid[Int] = new Monoid[Int] { | |
def zero = 0 | |
def append(a : Int, b : Int) = a+b | |
} | |
implicit def doubleMonoid : Monoid[Double] = new Monoid[Double] { | |
def zero = 0.0 | |
def append(a : Double, b : Double) = a+b | |
} | |
implicit def setMonoid[T]: Monoid[Set[T]] = new Monoid[Set[T]] { | |
def append(a: Set[T], b: Set[T]): Set[T] = a.++(b) | |
def zero: Set[T] = Set.empty | |
} | |
implicit def stringMonoid : Monoid[String] = new Monoid[String] { | |
def zero = "" | |
def append(a : String, b : String) = a+b | |
} | |
implicit val monoidInstance: ProductTypeClass[Monoid] = new ProductTypeClass[Monoid] { | |
def emptyProduct = new Monoid[HNil] { | |
def zero = HNil | |
def append(a : HNil, b : HNil) = HNil | |
} | |
def product[F, T <: HList](FHead : Monoid[F], FTail : Monoid[T]) = new Monoid[F :: T] { | |
def zero = FHead.zero :: FTail.zero | |
def append(a : F :: T, b : F :: T) = FHead.append(a.head, b.head) :: FTail.append(a.tail, b.tail) | |
} | |
def project[F, G](instance : => Monoid[G], to : F => G, from : G => F) = new Monoid[F] { | |
def zero = from(instance.zero) | |
def append(a : F, b : F) = from(instance.append(to(a), to(b))) | |
} | |
} | |
} | |
trait MonoidSyntax[T] { | |
def |+|(b : T) : T | |
} | |
object MonoidSyntax { | |
implicit def monoidSyntax[T](a : T)(implicit mt : Monoid[T]) : MonoidSyntax[T] = new MonoidSyntax[T] { | |
def |+|(b : T) = mt.append(a, b) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment