8

在尝试熟悉Control.Arrow时,我注意到Kleisli 新类型似乎承认 Functor 实例,例如:

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

没有提供此实例是否有原因?它是否作为孤立实例存在于某个包中?

4

2 回答 2

7

每个箭头都可以Functor通过定义变为有效

fmap f a = a >>> arr f

但是,由于它们的种类不同(需要而需要) ,因此不可能将Functora 声明为超类。所以每个箭头都需要单独定义实例。ArrowFunctor* -> *Arrow* -> * -> *

您可以用 包裹任何箭头ArrowMonad,然后给出一个Applicative实例(因此也是一个Functorinstance Arrow a => Applicative (ArrowMonad a) where ...:。

我看不出Kleisli缺少Functor实例的任何特殊原因。最有可能的是你不需要它。如果你想使用函数(或应用或单子)操作,你可以在原始单子上做。Kleisli只有在需要箭头接口时才将 monad 包装进去。

于 2013-09-20T20:57:09.547 回答
1

更新

inControl.Arrow已经定义:

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

更新 2

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

所以你需要使用Arrow Transformer或创建一个新Arrow类,比如

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

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

于 2013-09-20T20:48:04.260 回答