scala - How is List a monad? -
i think have basic grasp of monads , monadic operations still bit stuck on understanding how magic features of monadic type added underlying type (hope makes sense).
for example, was reading how list[t]
monad. if flatmap
, map
on lists sequentially in for
comprehension isn't flatmap
, map
providing monadic magic?
if create list<string>
how monadic magic added? or list<t>
monad in scala because happens 1 of containers language provides in-built monadic support for?
you're right flatmap
, map
providing "monadic magic." there fortunately or unfortunately (depending on how bad code you've seen) no magic in programming. no amount of abstraction save (or else) writing code thing want. abstraction "just" lets re-use written code , clarify thoughts around problem. monad concept, idea, abstraction, etc.
in case of scala literally compiler for
comprehension, becomes series of flatmap
, map
, withfilter
, , filter
statements.
a monad (in scala) can thought of label phenomenon happen have type constructor t[_]
, 2 functions1
def f0[a](x: t[a], f: x => t[a]): t[a] def f1[a](x: a): t[a]
by convention, when see phenomenon, scala community calls f0
flatmap
, make method x
parent class instead of separate argument. there convention call f1
point
or pure
(see scalaz
or cats
). f1
method doesn't end explicitly taking argument , uses parent class x
.
whenever says "such-and-such" monad, there implied f0
, f1
speaker expects listener infer. strictly speaking "list
monad" mild abuse of terminology. it's short-hand list
along functions (xs: list[a], f: => list[a]) => xs.map(f).flatten
(which forms f0
) , (x: a) => list(x)
(which forms f1
) form monad. or less obtusely, list
along standard flatmap
on lists , list.apply
constructor form monad.
therefore there never magic. part of classifying monad
had have provided notion of flatmap
, pure
.
there many ways turn abstraction of monad code. naive way (i.e. scala no third-party libraries) agree on common name f0
, f1
(e.g. flatmap
) , name methods have appropriate type signature names. scalac
expects for
comprehensions. go 1 step further , try formalize things trait
or abstract class
. maybe call monad
cute , have following:
trait monad[a] { def flatmap(f: => monad[a]): monad[a] def pure(x: a): monad[a] }
then might call extends monad
implementation of monad idea (you might imagine such class list[a] extends monad[a]
).
for variety of practical reasons turns out less satisfactory , end usual solution looks (hand-waving away lot of other complexity)
trait monad[f[_]] { def flatmap[a](f: => f[a]): f[a] def pure[a](x: a): f[a] }
that gets implemented implicit
s.
footnotes:
- and laws/conventions governing interaction. practical reason existence of laws lend sanity programmer's lives know expect when tells them these functions "monadic." these laws makes reasoning constructs such monads useful, won't delve them here because they're adequately explained elsewhere.
Comments
Post a Comment