The two expressions
y >> pure x
liftM (const x) y
have the same type signature in Haskell. I was curious whether they were equivalent, but I could neither produce a proof of the fact nor a counter example against it.
If we rewrite the two expressions so that we can eliminate the x
and y
then the question becomes whether the two following functions are equivalent
flip (>>) . pure
liftM . const
Note that both these functions have type Monad m => a -> m b -> m a
.
I used the laws that Haskell gives for monad, applicatives, and functors to transform both statements into various equivalent forms, but I was not able to produce a sequence of equivalences between the two.
For instance I found that y >> pure x
can be rewritten as follows
y >>= const (pure x)
y *> pure x
(id <$ y) <*> pure x
fmap (const id) y <*> pure x
and liftM (const x) y
can be rewritten as follows
fmap (const x) y
pure (const x) <*> y
None of these spring out to me as necessarily equivalent, but I cannot think of any cases where they would not be equivalent.
From HaskellWiki. A function is called pure if it corresponds to a function in the mathematical sense: it associates each possible input value with an output value, and does nothing else.
Definition. In Haskell, an applicative is a parametrized type that we think of as being a container for data of that type plus two methods pure and <*> . Consider a parametrized type f a . The pure method for an applicative of type f has type. pure :: a -> f a.
A monadic function is a function with a single argument, written to its right. It is one of three possible function valences; the other two are dyadic and niladic. The term prefix function is used outside of APL to describe APL's monadic function syntax.
Haskell is a pure language Being pure means that the result of any function call is fully determined by its arguments. Procedural entities like rand() or getchar() in C, which return different results on each call, are simply impossible to write in Haskell.
The other answer gets there eventually, but it takes a long-winded route. All that is actually needed are the definitions of liftM
, const
, and a single monad law: m1 >> m2
and m1 >>= \_ -> m2
must be semantically identical. (Indeed, this is the default implementation of (>>)
, and it is rare to override it.) Then:
liftM (const x) y
= { definition of liftM* }
y >>= \z -> pure (const x z)
= { definition of const }
y >>= \z -> pure x
= { monad law }
y >> pure x
* Okay, okay, so the actual definition of liftM
uses return
instead of pure
. Whatever.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With