Skip to content

Instantly share code, notes, and snippets.

@EnverOsmanov
Created April 12, 2018 14:00
Show Gist options
  • Save EnverOsmanov/2e4d5ce0aac795b6506602e8434bf117 to your computer and use it in GitHub Desktop.
Save EnverOsmanov/2e4d5ce0aac795b6506602e8434bf117 to your computer and use it in GitHub Desktop.
object Products {
import scala.language.higherKinds
case class Cat[A, B](name: A, age: B)
case class Dog(name: String, age: Int)
trait Product[P] {
type Fst
type Snd
def fst(p: P): Fst
def snd(p: P): Snd
}
object Product {
implicit def tuple2Product[A, B] = new Product[Tuple2[A, B]] {
type Fst = A
type Snd = B
override def fst(p: Tuple2[A,B]): A = p._1
override def snd(p: Tuple2[A,B]): B = p._2
}
implicit def catProduct[A, B] = new Product[Cat[A, B]] {
type Fst = A
type Snd = B
override def fst(p: Cat[A, B]): A = p.name
override def snd(p: Cat[A, B]): B = p.age
}
implicit val dogProduct = new Product[Dog] {
type Fst = String
type Snd = Int
override def fst(p: Dog): String = p.name
override def snd(p: Dog): Int = p.age
}
}
def fst[P](p: P)(implicit product: Product[P]) = product.fst(p)
def snd[P](p: P)(implicit product: Product[P]) = product.snd(p)
def main(args: Array[String]) {
val d = new Dog("Waf", 5)
println(fst(d))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment