Skip to content

Instantly share code, notes, and snippets.

@danclien
Last active January 3, 2016 04:18
Show Gist options
  • Save danclien/8407565 to your computer and use it in GitHub Desktop.
Save danclien/8407565 to your computer and use it in GitHub Desktop.
An attempt to use higher kinded types to "extend" the List and Option classes.
// Enter :paste mode
trait Length[M[_]] {
def length[A](xs: M[A]): Int
}
object Length {
implicit val LengthList: Length[List] = new Length[List] {
def length[A](xs: List[A]): Int = {
xs.length
}
}
implicit val LengthOption: Length[Option] = new Length[Option] {
def length[A](xs: Option[A]): Int = {
if(xs == None) 0
else 1
}
}
}
// Exit :paste mode
def len[M[_]: Length, A](xs: M[A]): Int = {
val l = implicitly[Length[M]]
l.length(xs)
}
val list = List(1,2,3,4)
val option: Option[Int] = Some(1)
len(list)
len(option)
// With "enrich my library" pattern
trait LengthOp[M[_], A] {
val l: Length[M]
val value: M[A]
def len: Int = l.length(value)
}
implicit def toLengthOp[M[_]: Length, A](xs: M[A]) = new LengthOp[M, A] {
val l = implicitly[Length[M]]
val value = xs
}
object LengthOp[A] {
val l = implicitly[Length[A]]
l.length()
}
list.len
option.len
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment