在monad上映射箭头

Mat*_*iak 5 haskell arrows category-abstractions

据我所知,一个箭头是Profunctor,其中一个可以将其输入和输出,而是一个可以映射一个箭头一个仿函数?

据我所知,答案是"不",因为fmap函数类型签名是(a -> b) -> f a -> f b并且不承认Arrow a b,但我希望我所要求的是清楚的.

我正在寻找一种方式,例如,变换Maybe输入带有箭头,在NothingNothingJust xJust y哪里y是将箭头的结果x.

lef*_*out 7

Arrow结合了两个概念.正如你所说,其中一个就是一个profunctor,但首先它只是一个特定的类别类别(实际上是超类证据).

这与这个问题高度相关:是的,签名fmap(a -> b) -> f a -> f b,但实际上这几乎不是一个仿函数可以做的全部通用!在数学,函子是两个类别之间的映射Çd,在每个箭头分配Ç向箭头d.不同类别的箭头,就是这样!标准Functor类仅捕获最简单的特殊情况,即Hask类别中的endofunctors.

仿函数类的完整通用版本实际上看起来更像这样(这里是我的约束类别版本):

class (Category r, Category t) => Functor f r t | f r -> t, f t -> r where
  fmap :: r a b -> t (f a) (f b)
Run Code Online (Sandbox Code Playgroud)

或者,在伪语法中,

class (Category (??>), Category (~>)) => Functor f (??>) (~>) where
  fmap :: (a ??> b) -> f a ~> f b
Run Code Online (Sandbox Code Playgroud)

当其中一个类别是正确的箭头而不是普通的功能类别时,这肯定也可以工作.例如,您可以定义

instance Functor Maybe (Kleisli [] (->)) (Kleisli [] (->)) where
  fmap (Kleisli f) = Kleisli mf
   where mf Nothing = [Nothing]
         mf (Just a) = Just <$> f a
Run Code Online (Sandbox Code Playgroud)

用得像

> runKleisli (fmap . Kleisli $ \i -> [0..i]) $ Nothing
[Nothing]
> runKleisli (fmap . Kleisli $ \i -> [0..i]) $ Just 4
[Just 0,Just 1,Just 2,Just 3,Just 4]
Run Code Online (Sandbox Code Playgroud)

如果使用标准的profunctor-ish箭头,不确定这对于任何非常重要的事情是否有用.这是在其他类别这是绝对有用的 Hask -profunctors,例如

instance (TensorSpace v) => Functor (Tensor s v) (LinearFunction s) (LinearFunction s)
Run Code Online (Sandbox Code Playgroud)

表示你可以在张量积的单个因子上映射线性函数(而通常不可能在这样的乘积上映射非线性函数 - 结果将取决于向量空间的基础选择).