In Haskell, you can use the bind operator (>>=
) like this:
repli :: [a] -> [a]
repli xs = xs >>= \x -> [x,x]
*Main> repli [1,2,3]
[1,1,2,2,3,3]
I've read that flatMap
is Scala's bind operator:
def repli [A](xs: List[A]): List[A] =
xs.flatMap { x => List(x,x) }
scala> repli (List(1,2,3))
res0: List[Int] = List(1, 1, 2, 2, 3, 3)
As a pedagogic exercise, I'm trying to add support for >>=
to Scala:
class MyList[T](list: List[T]) {
def >>= [U](f: T => List[U]): List[U] = list.flatMap(f)
}
implicit def list2mylist[T](list: List[T]) = new MyList(list)
def repliNew [A](xs: List[A]): List[A] =
xs >>= { x: A => List(x,x) }
scala> repliNew (List(1,2,3))
res1: List[Int] = List(1, 1, 2, 2, 3, 3)
This works perfectly, but only for Lists. I really want to support any class with a flatMap
method. Whats the best way to go about this?
Scalaz does it as follows:
With implicit conversions from
M[A]
toMA[M, A]
for allM[_]
andA
:You just need a trait
Monad
and an instance of it for every monad you care about:What about adding a synonym for
flatMap
with an implicit class?With this in scope any object having the method
flatMap
will also have>>=
.