Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Created September 10, 2013 01:15
Show Gist options
  • Save xuwei-k/6503788 to your computer and use it in GitHub Desktop.
Save xuwei-k/6503788 to your computer and use it in GitHub Desktop.
scala collection monad
scalaVersion := "2.10.2"
import scala.collection.generic.{GenericTraversableTemplate, GenericCompanion, CanBuildFrom}
import collection.{GenTraversableLike, GenTraversable}
// https://github.com/scalaz/scalaz/blob/v7.1.0-M2/core/src/main/scala/scalaz/std/IndexedSeq.scala
trait Functor[F[_]]{
def map[A, B](fa: F[A])(f: A => B): F[B]
}
trait Monad[F[_]] extends Functor[F]{
def unit[A](a: A): F[A]
override def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(a => unit(f(a)))
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}
trait GenTraversableMonad{
type CC[+A] <: GenTraversable[A] with GenericTraversableTemplate[A, CC] with GenTraversableLike[A, CC[A]]
protected def companion: GenericCompanion[CC]
protected implicit def canBuildFrom[A, B]: CanBuildFrom[CC[A], B, CC[B]]
implicit val instance: Monad[CC] =
new Monad[CC]{
def flatMap[A, B](fa: CC[A])(f: A => CC[B]) = fa flatMap f
def unit[A](a: A) = companion.apply(a)
override def map[A, B](fa: CC[A])(f: A => B) = fa map f
}
}
object VectorMonad extends GenTraversableMonad{
override type CC[+A] = Vector[A]
protected def companion = Vector
protected implicit def canBuildFrom[A, B] = Vector.canBuildFrom
}
object ListMonad extends GenTraversableMonad{
override type CC[+A] = List[A]
protected def companion = List
protected implicit def canBuildFrom[A, B] = List.canBuildFrom
}
object StreamMonad extends GenTraversableMonad{
override type CC[+A] = Stream[A]
protected def companion = Stream
protected implicit def canBuildFrom[A, B] = Stream.canBuildFrom
}
object Main extends App {
import ListMonad._
implicitly[Monad[List]].flatMap(List(1)){a => List(a)}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment