I just asked this on haskell-cafe, but I figure I might as well ask here too. Is the following Monad
instance for Backwards m
valid?
{-# Language RecursiveDo #-}
import Control.Applicative.Backwards
import Control.Monad.Fix
instance MonadFix m => Monad (Backwards m) where
m >>= f = Backwards $
do
fin <- forwards (f int)
int <- forwards m
pure fin
If so, could I also add this?
instance MonadFix m => MonadFix (Backwards m) where
mfix f = Backwards $ mfix (forwards . f)
The return function is derived from pure, since all Monads are also Applicatives. The bind function ( >>=) first applies the input r to f to give an a. It then applies the a to g to return a function from ( r -> b ). The input r is then applied to this function to return the final b.
instance Monad (r ->) where -- return :: a -> m a return = pure -- (>>=) :: m a -> (a -> m b) -> m b f >>= g = -> g (f r) r -- f is ( -> a), g is (\a -> -> b) The return function is derived from pure, since all Monads are also Applicatives. The bind function ( >>=) first applies the input r to f to give an a.
In addition to defining a wrapping monadic type, monads define two operators: one to wrap a value in the monad type, and another to compose together functions that output values of the monad type (these are known as monadic functions ).
Keep going and let’s have a look at several sample implementations of Monad pattern. My first motivational example was with Nullable<T> and ?.. The full pattern containing either 0 or 1 instance of some type is called Maybe (it maybe has a value, or maybe not).
No, it is not valid; the monad laws at best hold in some approximate fashion. As Petr Pudlák's answer shows, Backwards m >>= f
does not behave very nicely when f
is strict in its argument.
According to the monad laws,
pure () >>= (\() -> m) = m
But with this instance, if I'm not mistaken,
pure () >>= (\() -> m) = Backwards $ do
fin <- forwards (int `seq` m)
int <- pure ()
pure fin
= Backwards $ fmap fst $ mfix $ \ ~(_, int) -> do
fin <- forwards (int `seq` m)
pure (fin, ())
If the underlying monad is "strict" (i.e., its >>=
is strict in its left operand), this will diverge.
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