Why can applicative functors have side effects, but functors can't?

后端 未结 4 1362
既然无缘
既然无缘 2020-12-29 07:03

I\'m feeling rather silly asking this question, but it\'s been on my mind for a while and I can\'t find any answers.

So the question is: why can applicative functors

4条回答
  •  孤城傲影
    2020-12-29 07:30

    It is not true that Functors don't have effects. Every Applicative (and every Monad through WrappedMonad) is a Functor. The main difference is that Applicative and Monad give you tools how to work with those effects, how to combine them. Roughly

    • Applicative allows you to sequence effects and combine values inside.
    • Monad in addition allows you to determine a next effect according to the result of a previous one.

    However Functor only allows you to modify the value inside, it doesn't give tools to do anything with the effect. So if something is just Functor and not Applicative, it doesn't mean it doesn't have effects. It just doesn't have a mechanism how to combine them in this way.

    Update: As an example, consider

    import Control.Applicative
    
    newtype MyF r a = MyF (IO (r, a))
    
    instance Functor (MyF r) where
        fmap f (MyF x) = MyF $ fmap (fmap f) x
    

    This is clearly a Functor instance that carries effects. It's just that we don't have a way how to define operations with these effects that would comply to Applicative. Unless we impose some additional constraints on r, there is no way how to define an Applicative instance.

提交回复
热议问题