Monad-left unit law does not seem to hold true for lists in scala. Are there scala lists of non-monads?

Monads "left single law":

unit(x) flatMap f == f(x)

      

But:

(List(1) flatMap ((x: Int) => Some[Int](x))) == List(1) // true
((x: Int) => Some[Int](x))(1) == Some(1) // also true

      

So the left element law is not true for lists in scala. Are there lists, not monads?

+3


source to share


2 answers


First, the law of the monad takes f: A => M[A]

(here f: A => List[A]

). This does not apply to (x: Int) => Some[Int](x)

.

Secondly, List

flatMap

it is not monadic binding. It is more general than bind because it accepts an implicit one CanBuildFrom

, which allows it to change its return type depending on what you want to return. You can restrict it by binding like so

def bind[A](xs: List[A])(f: A => List[A]) = xs.flatMap(f) // implicit (List.canBuildFrom)

      



Now you can see that the law is satisfied:

bind(List(1))(x => List(x, x)) == List(1, 1)

      

+7


source


I'm not a category theory or a Haskell expert, but I don't understand your question, and my answer is too long for comments, let alone that blocks of code look terrible in comments.

Haskell's law of legality is return a >>= f ≡ f a

, right?

In Scala:

return -> apply
>>=    -> flatMap

      

So the left-identity law for Scala List

would beList(a).flatMap(f) = f(a)



In your case, val a = 1

and val f = (x: Int) => Some[Int](x)

. But it doesn't even compile because it Option

doesn't GenTraversableOnce

; you cannot return Option

from List.flatMap

.

Instead, if we define the val f = (x: Int) => List(x * 2)

double function

LHS: List(a).flatMap(f) = List(2)
RHS: f(a) = List(2)

      

LHS = RHS, left identity satisfied.

Did I miss something?

+1


source







All Articles