Monads Not With "flatmap" But "flatunit"?
Solution 1:
In this answer, I won't dwell on flatUnit
. As others have pointed out, join . return = id
for any monad (it is one of the monad laws), and so there isn't much to talk about it in and of itself. Instead, I will discuss some of the surrounding themes raised in the discussion here.
Quoting a comment:
in other words, functor with a flat structure, it's a monad.
This, I believe, is the heart of the question. A monad need not be a functor with a flat structure, but a functor whose values can be flattened (with join
) in a way that follows certain laws ("a monoid in the category of endofunctors", as the saying goes). It isn't required for the flattening to be a lossless operation (i.e. for join
to be an isomorphism).
Monads whose join
is an isomorphism are called, in category theory parlance, idempotent monads . For a Haskell Monad
to be idempotent, though, the monadic values must have no extra structure. That means most monads of immediate interest to a programmer won't be idempotent (in fact, I'm having trouble to think of idempotent Haskell Monad
s that aren't Identity
or identity-like). One example already raised in the comments was that of lists:
join [[1,2],[3,4,5]] = [1,2,3,4,5] -- Grouping information discarded
The function/reader monad gives what I'd say is an even more dramatic illustration:
join (+) = \x -> x + x
This recent question gives an interesting illustration involving Maybe
. The OP there had a function with signature...
appFunc :: Integer -> Integer -> Bool -> Maybe (Integer,Integer)
... and used it like this...
appFunc <$> u <*> v <*> w
... thus obtaining a Maybe (Maybe (Integer, Integer))
result. The two layers of Maybe
correspond to two different ways of failing: if u
, v
or w
are Nothing
, we get Nothing
; if the three of them are Just
-values but appFunc
results in Nothing
, we get Just Nothing
; finally, if everything succeeds we get a Just
-value within a Just
. Now, it might be the case that we, like the author of that question, didn't care about which layer of Maybe
led to the failure; in that case, we would discard that information, either by using join
on the result or by rewriting it as u >>= \x -> v >>= \y -> w >>= \b -> appFunc x y b
. In any case, the information is there for us to use or discard.
Note 1: In Combining Monads by King and Wadler (one of Wadler's papers about monads), the authors introduce a different, and largely unrelated, meaning for "idempotent monad". In their sense, an idempotent monad is one for which (in applicative notation) f <$> u <*> u = (\x -> f x x) <$> u
-- one example would be Maybe
.
Post a Comment for "Monads Not With "flatmap" But "flatunit"?"