Yesterday we looked at Monad
typeclass, which introduces flatMap
. We looked at how monadic chaining can add contexts to values. Because both Option
and List
already have flatMap
in the standard library, it was more about changing the way we see things rather than introducing new code. We also reviewed for
syntax as a way of chaining monadic operations.
There’s a subtle difference in Haskell’s do
notation and Scala’s for
syntax. Here’s an example of do
notation:
foo = do
x <- Just 3
y <- Just "!"
Just (show x ++ y)
Typically one would write return (show x ++ y)
, but I wrote out Just
, so it’s clear that the last line is a monadic value. On the other hand, Scala would look as follows:
scala> def foo = for {
x <- 3.some
y <- "!".some
} yield x.shows + y
Looks almost the same, but in Scala x.shows + y
is plain String
, and yield
forces the value to get in the context. This is great if we have the raw value. But what if there’s a function that returns monadic value?
in3 start = do
first <- moveKnight start
second <- moveKnight first
moveKnight second
We can’t write this in Scala without extract the value from moveKnight second
and re-wrapping it using yeild:
def in3: List[KnightPos] = for {
first <- move
second <- first.move
third <- second.move
} yield third
This difference shouldn’t pose much problem in practice, but it’s something to keep in mind.