在尝试熟悉 Control.Arrow 时,我注意到 Kleisli 新类型似乎会承认 Functor 实例,例如:
instance Monad m => Functor (Kleisli m a) where
fmap f (Kleisli k) = Kleisli $ liftM f . k
不提供此实例是否有原因?它是否作为孤立实例存在于某个包中?
通过定义
,每个箭头都可以成为有效的
Functor
fmap f a = a >>> arr f
但是,不可能将
Functor
声明为 Arrow
的超类,因为它们的类型不同(Functor
需要 * -> *
,而 Arrow
需要 * -> * -> *
)。所以每个箭头都需要单独定义实例。
您可以用
ArrowMonad
包裹任何箭头,然后给出一个 Applicative
实例(因此也是一个 Functor
):instance Arrow a => Applicative (ArrowMonad a) where ...
。
我没有看到
Kleisli
缺少 Functor
实例的任何特殊原因。最有可能的是您不需要它。如果你想使用函子(或应用或单子)操作,你可以在原始单子上进行。仅当需要箭头界面时,才将 monad 包装到 Kleisli
中。
更新
in
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)
Package arrows包含一些示例,但它没有实现
Free