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

后端 未结 4 1446
既然无缘
既然无缘 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:44

    This answer is a bit of an over-simplification, but if we define side effects as computations being affected by previous computations, it's easy to see that the Functor typeclass is insufficient for side effects simply because there is no way to chain multiple computations.

    class Functor f where
        fmap :: (a -> b) -> f a -> f b
    

    The only thing a functor can do is to alter the end result of a computation via some pure function a -> b.

    However, an applicative functor adds two new functions, pure and <*>.

    class Functor f => Applicative f where
        pure   :: a -> f a
        (<*>)  :: f (a -> b) -> f a -> f b
    

    The <*> is the crucial difference here, since it allows us to chain two computations: f (a -> b) (a computation which produces a function) and f a a computation that provides the parameter to which the function is applied. Using pure and <*> it's possible to define e.g.

    (*>) :: f a -> f b -> f b
    

    Which simply chains two computations, discarding the end result from the first one (but possibly applying "side effects").

    So in short, it's the ability to chain computations which is the minimum requirement for effects such as mutable state in computations.

提交回复
热议问题