Defining a new monad in haskell raises no instance for Applicative

后端 未结 2 1402
太阳男子
太阳男子 2020-12-04 23:34

I am trying to define a new monad and I am getting a strange error

newmonad.hs

newtype Wrapped a = Wrap {unwrap :: a}
instance Monad Wrap         


        
相关标签:
2条回答
  • 2020-12-04 23:59

    This is the Applicative Monad Proposal (AMP). Now whenever you declare something as Monad, you also have to declare it as Applicative (and therefore Functor). Mathematically speaking, every monad is an applicative functor, so this makes sense.

    You can do the following to remove the error:

    instance Functor Wrap where
      fmap f (Wrap x) = Wrap (f x)
    
    instance Applicative Wrap where
      pure = Wrap
      Wrap f <*> Wrap x = Wrap (f x)
    

    https://wiki.haskell.org/Functor-Applicative-Monad_Proposal

    Edit: Maybe I should point out more clearly that this is a recent thing? The code you posted used to work before, but with recent versions of GHC you'll get an error. It's a breaking change.

    Edit: The following declarations should work for any monad:

    import Control.Applicative -- Otherwise you can't do the Applicative instance.
    import Control.Monad (liftM, ap)
    
    instance Functor ??? where
      fmap = liftM
    
    instance Applicative ??? where
      pure  = return
      (<*>) = ap
    

    Depending on the monad in question, there may be more efficient implementations possible, but this is a simple starting point.

    0 讨论(0)
  • 2020-12-05 00:05

    The most normalized and unobtrusive answer is :-

    as Monad is dependent upon Applicative

    class Applicative m => Monad m where ...

    and Applicative is dependent upon Functor

    class Functor f => Applicative f where ...

    we need the instance definitions

    > instance Functor Wrapped where
    >     fmap = liftM
    

    and

    > instance Applicative Wrapped where
    >     pure = return
    >     (<*>) = ap
    
    0 讨论(0)
提交回复
热议问题