Reputation: 15363
I am reading James Iry's blog post on Monads in scala. I am in part three and I am confused about his description of the second law of monads regarding Unit. Specifically this claim:
unit(x) flatMap f = f(x)
When I apply my mental examples which are jame's previous examples of monadic types this never seems to work out
val x = 1
val f = (_:Int) * 2
f(x) == 2 //true
List(x) flatMap f == 2 //fail
Some(x) flatMap f == 2 //fail
As a matter of fact they don't even compile due to type issues.
To clarify I understand why these are failing. I understand the how to fix them so they compile.
My confusion is that these seem to be in conflict with the theory presented in the article. Is there a step I am missing? Are these types not really monads? Is the section entitled "Second Law of Monads:Unit" incorrect?
Upvotes: 4
Views: 745
Reputation: 71590
The fact that it doesn't compile due to type issues should tell you something: f
is not the kind of function that the monad law applies to!
flatMap
, when seen as a monadic operation rather than a collection operation, takes a "monadic value" and a function from ordinary values to monadic values. Your f
function is a function from ordinary values to ordinary values.
Passing f
to flatMap
doesn't break the monadic laws, it just doesn't mean anything at all. It's an invalid expression. Similarly 1 + "fork" - 1
doesn't violate the law from arithmetic that 1 + x - 1 = x
; from this law we might conclude that 1 + "fork" - 1
should equal "fork", when in fact it's a compiler error. That would be a silly conclusion though; the laws are only talking about things that are type-correct.
Upvotes: 8
Reputation: 207006
Scala's flatMap
needs a function that returns a collection, not a function that returns a single element, like your function f
.
Either use map
:
List(x) map f
or make your function return a collection:
val f = (x: Int) => List(x * 2)
List(x) flatMap f
Note that it will also return a collection, not a single integer (you'll get List(2)
, not just 2
).
Upvotes: 9