Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Backwards admit a Monad instance?

Tags:

haskell

monads

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)
like image 800
dfeuer Avatar asked Dec 15 '15 20:12

dfeuer


People also ask

How do you return a function from a monad?

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.

What is the difference between return() and bind() in monad?

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.

What is a monad type?

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 ).

What are some sample implementations of the monad pattern?

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).


Video Answer


1 Answers

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.

like image 127
dfeuer Avatar answered Sep 26 '22 12:09

dfeuer