haskell - Monads with Join() instead of Bind() -
monads explained in turns of return
, bind
. however, gather can implement bind
in terms of join
(and fmap
?)
in programming languages lacking first-class functions, bind
excruciatingly awkward use. join
, on other hand, looks quite easy.
i'm not sure understand how join
works, however. obviously, has [haskell] type
join :: monad m => m (m x) -> m x
for list monad, trivially , concat
. general monad, what, operationally, method do? see type signatures, i'm trying figure out how i'd write in, say, java or similar.
(actually, that's easy: wouldn't. because generics broken. ;-) in principle question still stands...)
oops. looks has been asked before:
could sketch out implementations of common monads using return
, fmap
, join
? (i.e., not mentioning >>=
@ all.) think perhaps might sink in dumb brain...
without plumbing depths of metaphor, might suggest read typical monad m
"strategy produce a", type m value
first class "strategy produce value". different notions of computation or external interaction require different types of strategy, general notion requires regular structure make sense:
- if have value, have strategy produce value (
return :: v -> m v
) consisting of nothing other producing value have; - if have function transforms 1 sort of value another, can lift strategies (
fmap :: (v -> u) -> m v -> m u
) waiting strategy deliver value, transforming it; - if have strategy produce strategy produce value, can construct strategy produce value (
join :: m (m v) -> m v
) follows outer strategy until produces inner strategy, follows inner strategy way value.
let's have example: leaf-labelled binary trees...
data tree v = leaf v | node (tree v) (tree v)
...represent strategies produce stuff tossing coin. if strategy leaf v
, there's v
; if strategy node h t
, toss coin , continue strategy h
if coin shows "heads", t
if it's "tails".
instance monad tree return = leaf
a strategy-producing strategy tree tree-labelled leaves: in place of each such leaf, can graft in tree labels it...
join (leaf tree) = tree join (node h t) = node (join h) (join t)
...and of course have fmap
relabels leaves.
instance functor tree fmap f (leaf x) = leaf (f x) fmap f (node h t) = node (fmap f h) (fmap f t)
here's strategy produce strategy produce int
.
toss coin: if it's "heads", toss coin decide between 2 strategies (producing, respectively, "toss coin producing 0 or producing 1" or "produce 2"); if it's "tails" produce third ("toss coin producing 3 or tossing coin 4 or 5").
that join
s make strategy producing int
.
what we're making use of fact "strategy produce value" can seen value. in haskell, embedding of strategies values silent, in english, use quotation marks distinguish using strategy talking it. join
operator expresses strategy "somehow produce follow strategy", or "if told strategy, may use it".
(meta. i'm not sure whether "strategy" approach suitably generic way think monads , value/computation distinction, or whether it's crummy metaphor. find leaf-labelled tree-like types useful source of intuition, perhaps not surprise they're free monads, enough structure monads @ all, no more.)
ps type of "bind"
(>>=) :: m v -> (v -> m w) -> m w
says "if have strategy produce v
, , each v follow-on strategy produce w
, have strategy produce w
". how can capture in terms of join
?
mv >>= v2mw = join (fmap v2mw mv)
we can relabel our v
-producing strategy v2mw
, producing instead of each v
value w
-producing strategy follows on — ready join
!
Comments
Post a Comment