Earlier today on the elm-lang slack I witnessed a discussion about Monads that I found amazing. It was a quasi-Socratic-Dialogue style exposition of what Monads are all about, how you get them in Elm, and why those Haskell kids like them so much. The discussion took place between @hoelzro and @opsb. Behold:
@opsb: As someone that has never done much functional programming I'm curious where Monads are used in Elm (as I'd have trouble describing what they are). Am I right in thinking that anything with an
andThen
function is a Monad?
hoelzro: @opsb
andThen
can be seen as Haskell's>>=
, imo
opsb: My experience is mostly OO with a sprinkling of Elixir so
>>=
doesn't mean anything to me (yet - I have started working through Haskell Programming)
hoelzro: oh, my bad
>>=
is the function used in Haskell to pass a value in one instance of a monad to a function and generate a new instance of that monad
opsb: ok, that makes sense from where I've seen
andThen
used
hoelzro: iirc, though,
>>=
takes a(a -> m b)
function, butandThen
takes(a -> b)
so it's not quite the same
opsb: so with
>>=
you have to return a wrapped result?
enetsee: @opsb : a monad is kind of like an OOP interface, it has two ‘methods’ one of which is
return
and the other isbind
. Elm’sandThen
isbind
. The equivalent ofreturn
depends on the data type - forList
it has typea -> List a
implemented withsingleton x = [x]
and forMaybe
it has typea -> Maybe a
implementationjust x = Just x
(edited)
opsb: So
return
"lifts" a value into a Monad?
enetsee: exactly
opsb: awesome, it's making sense
re:
(a -> m b)
what's the m here?
enetsee: @opsb replace
m
with whatever data type you are working with, e.g.List
,Maybe
,Result
...
opsb: right
enetsee: Other languages allow you to abstract this pattern (which is generally the source of confusion) but Elm makes you implement it explicitly for each data type
opsb:
andThen : Maybe a -> (a -> Maybe b) -> Maybe b
ah, I see, right, my understanding was the inverse. Makes sense now
hoelzro: huh, I guess
andThen
is(a -> m b)
opsb: yeah
enetsee: @hoelzro no -
andThen
ism a -> (a -> m b) -> m b
for some typem
hoelzro: sorry, I meant the function provided to
andThen
I was correcting myself here. iirc, though,>>=
takes a(a -> m b)
function, butandThen
takes(a -> b)
opsb: So that seems to be the same as bind in haskell?
enetsee: it is exactly
bind
opsb: But in haskell you wouldn't need to write the
andThen
, you just use>>=
and it magically works? (edited)
hoelzro: you don't even need to do that
you can
but Haskell's
do
notation wires everything up for you
opsb: ha
I keep hearing that being referenced
enetsee: @opsb, haskell has these things called
type classes
(which are again, like interfaces). To use>>=
you have to declare aninstance
ofMonad
for your data type
hoelzro: so something like this:
greet = do
name <- prompt "What's your name?"
putStrLn $ "Hello, " ++ name
is just sugar for this:
(prompt "What's your name?") >>= (\name -> putStrLn $ "Hello, " ++ name)
enetsee: The difference with haskell is that you can then write a function once for all data types that declare that interface
enetsee: yep
opsb: seems very similar to piping
hoelzro: well, the cool thing about
>>=
versus piping is that if you make your own monad, you dictate exactly how>>=
works
opsb: right
hoelzro: so you could (in theory) write a monad that imposes an implicit one second delay in between statements
that's why some people refer to monads as "programmable semicolons"
opsb: could you potentially pass multiple params where
\name
is?
hoelzro: you cannot
since the signature is
m a -> (a -> m b) -> m b
opsb: gotcha
hoelzro: you could, however, return a tuple
opsb: so
do
is essentially a monadic pipeline?or is ordering not important?
enetsee: @opsb you’re getting this very quickly :)
@opsb ordering is important
opsb: right, I was seeing the similarity to
let
(but they're obviously not that similar)
enetsee: @opsb if you rewrite it as a series of
binds
and functions taking monadic values you will see that you can’t carry on in the pipeline until the previous value is evaluated
opsb: This is one of the things I'm finding very attractive about functional languages, they do things I've wanted to do in the past :)
yep, that's clear now
ok, well that went well :)
learned a lot, thank you very much!
Anyway, I just wanted to share it because it was...just so nice :) I especially liked how foodstuff didn't have to enter the equation, and instead its typical stage-entry was replaced by two adult humans conversing.
Cheers!