简体   繁体   English

在monad上映射箭头

[英]fmapping arrows over monads

I understand that an Arrow is a Profunctor, where one can transform its input and its output, but can one map an arrow over a Functor? 据我所知,一个箭头是Profunctor,其中一个可以将其输入和输出,而是一个可以映射一个仿函数的箭头?

I understand that as-asked the answer is "no", since the fmap function type signature is (a -> b) -> fa -> fb and does not admit Arrow ab , but I hope what I'm asking is clear. 据我所知,答案是“不”,因为fmap函数类型签名是(a -> b) -> fa -> fb而且不承认Arrow ab ,但我希望我所要求的是清楚的。

I am looking for a way to, for example, transform a Maybe input with an Arrow, where Nothing goes to Nothing and Just x goes to Just y where y is the result of applying the Arrow to x . 我正在寻找一种方法,例如,使用箭头转换一个Maybe输入,其中Nothing转到NothingJust x转到Just y ,其中y是将箭头应用于x

Arrow combines two concepts. Arrow结合了两个概念。 One of them, as you say, is that of a profunctor, but first of all it's just a specific class of categories (as indeed the superclass evidences). 正如你所说,其中一个就是一个profunctor,但首先它只是一个特定的类别类别 (实际上是超类证据)。

That's highly relevant for this question: yes, the signature of fmap is (a -> b) -> fa -> fb , but actually that is not nearly the full generality of what a functor can do! 这与这个问题高度相关:是的, fmap的签名是(a -> b) -> fa -> fb ,但实际上这几乎不是函子可以做的全部通用! In maths, a functor is a mapping between two categories C and D , that assigns each arrow in C to an arrow in D . 在数学中,算符是两类Cd,C的每个箭头分配给在d中的箭头之间的映射。 Arrows in different categories, that is! 不同类别的箭头,就是这样! The standard Functor class merely captures the simplest special case, that of endofunctors in the Hask category. 标准的Functor类仅捕获最简单的特殊情况,即Hask类别中的endofunctors

The full general version of the functor class actually looks more like this (here my version from constrained-categories ): 仿函数类的完整通用版本实际上看起来更像这样(这里是我的约束类别版本):

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)

Or, in pseudo-syntax, 或者,在伪语法中,

class (Category (──>), Category (~>)) => Functor f (──>) (~>) where
  fmap :: (a ──> b) -> f a ~> f b

This can sure enough also work when one of the categories is a proper arrow rather than an ordinary function category. 当其中一个类别是正确的箭头而不是普通的功能类别时,这肯定也可以工作。 For instance, you could define 例如,您可以定义

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

to be used like 用得像

> 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]

Not sure whether this would be useful for anything nontrivial, if using the standard profunctor-ish arrows. 如果使用标准的profunctor-ish箭头,不确定这对于任何非常重要的事情是否有用。 It is definitely useful in other categories which are not Hask -profunctors, for instance 这是在其他类别不属于 Hask -profunctors肯定是有用的, 例如

instance (TensorSpace v) => Functor (Tensor s v) (LinearFunction s) (LinearFunction s)

expressing that you can map a linear function over a single factor of a tensor product (whereas it's generally not possible to map a nonlinear function over such a product – the result would depend on a choice of basis on the vector space). 表示你可以在张量积的单个因子上映射线性函数(而通常不可能在这样的乘积上映射非线性函数 - 结果将取决于向量空间的基础选择)。

I am looking for a way to, for example, transform a Maybe input with an arrow, where Nothing goes to Nothing and Just x goes to Just y where y is the result of applying the Arrow to x . 我正在寻找一种方法,例如,用箭头转换一个Maybe输入,其中Nothing转到NothingJust x转到Just y ,其中y是将箭头应用于x

This can be implemented for specific Functor s (such as Maybe ), though ArrowChoice will likely be necessary: 这可以针对特定的Functor (例如Maybe )实现,虽然ArrowChoice可能是必要的:

maybeAmap :: ArrowChoice p => p a b -> p (Maybe a) (Maybe b)
maybeAmap p =
    maybe (Left ()) Right
    ^>> returnA +++ p
    >>^ const Nothing ||| Just

See Arrow equivalent of mapM? 请参阅箭头等效于mapM? for a similar function written in proc-notation. 用于在proc-notation中编写的类似函数。

Speaking of mapM , profunctors has an interesting class called Traversing : 说到mapMprofunctors一个名为Traversing的有趣类

-- Abbreviated class definition:
class (Choice p, Strong p) => Traversing p where
  traverse' :: Traversable f => p a b -> p (f a) (f b)
  wander :: (forall f. Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t

The flag-bearer instance of Traversing is the one for the Star profunctor , which provides an alternative encoding of the familiar traverse function. Traversing的旗帜实例是Star profunctor的实例 ,它提供熟悉的traverse函数的替代编码。 Note that, while leftaroundabout's answer demonstrates a non- Hask functor for categories which are not necessarily Hask -profunctors, with Traversing we have a construction for Profunctor s that do not necessarily have a Category instance. 需要注意的是,虽然leftaroundabout的回答表明非Hask仿函数为其不一定Hask -profunctors类,用Traversing我们有一个建筑Profunctor s表示不一定有Category的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM