为什么在Control.Arrow中没有Kleisli的Functor实例?

时间:2013-09-20 20:10:56

标签: haskell functor arrows

在尝试熟悉Control.Arrow时,我注意到Kleisli newtype似乎会接受Functor实例,例如:

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

是否有理由不提供此实例?它是否作为孤立实例存在于某个包中?

2 个答案:

答案 0 :(得分:7)

通过定义

,每个箭头都可以成为有效的Functor
fmap f a = a >>> arr f

但是,由于Functor需要Arrow需要Functor* -> *需要Arrow,因此无法将* -> * -> *声明为ArrowMonad的超类{1}})。因此,每个箭头都需要单独定义实例。

您可以使用Applicative包装任何箭头,然后提供Functor个实例(因此也是instance Arrow a => Applicative (ArrowMonad a) where ...):Kleisli

我没有看到Functor缺少Kleisli实例的任何特殊原因。最可能的似乎是你不需要它。如果您想使用functorial(或applicative或monadic)操作,可以在原始monad上执行。当您需要箭头界面时,只需将monad包装到{{1}}。

答案 1 :(得分:1)

<强>更新

Control.Arrow中的

已定义:

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

更新2

如果您希望将Free Monad插入Kleisli - 这是不可能的,Free还有一个额外参数f

因此,您需要使用Arrow Transformer或创建新的Arrow类,例如

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

arrows包含一些示例,但未实现Free