在尝试熟悉Control.Arrow时,我注意到Kleisli newtype似乎会接受Functor实例,例如:
instance Monad m => Functor (Kleisli m a) where
fmap f (Kleisli k) = Kleisli $ liftM f . k
是否有理由不提供此实例?它是否作为孤立实例存在于某个包中?
答案 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