Why there isn't a Functor instance for Kleisli in Control.Arrow?

可紊 提交于 2019-12-08 17:00:49

问题


While trying to familiarize myself with Control.Arrow, I have noticed that the Kleisli newtype would seem to admit a Functor instance, something like:

instance Monad m => Functor (Kleisli m a) where
    fmap f (Kleisli k) = Kleisli $ liftM f . k

Is there a reason why this instance isn't provided? Does it exist in some package as an orphan instance?


回答1:


Every arrow can be made into a valid Functor by defining

fmap f a = a >>> arr f

However it's not possible to declare a Functor to be a superclass of Arrow because of their different kinds (Functor needs * -> * while Arrow needs * -> * -> *). So every arrow needs to define the instance separately.

You can wrap any arrow with ArrowMonad, which then gives an Applicative instance (and therefore also a Functor): instance Arrow a => Applicative (ArrowMonad a) where ....

I don't see any particular reason why Kleisli lacks the Functor instance. The most probable seems to be that you don't need it. If you want to use functorial (or applicative or monadic) operations, you do it on the original monad. You only wrap the monad into Kleisli when you need the arrow interface.




回答2:


UPDATE

in Control.Arrow is already defined:

(>>^) :: Arrow a => a b c -> (c -> d) -> a b d
(^<<) :: Arrow a => (c -> d) -> a b c -> a b d

UPDATE 2

If you wish to insert Free Monad into Kleisli - it is impossible, Free has one extra parameter f.

So you need to use Arrow Transformer or create a new Arrow class, like

class Arrow a => ArrowFunctor f a | a -> f where
    afmap :: a b (f c)

Package arrows consist some examples, but it not implement Free



来源:https://stackoverflow.com/questions/18925045/why-there-isnt-a-functor-instance-for-kleisli-in-control-arrow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!