使用Arrows的一些功能非常便于在对上使用。但我无法理解这些功能的类型如何与一对结合起来。一般来说,我发现箭头相关函数的类型非常混乱。
例如,我们有first :: a b c -> a (b, d) (c, d)
,这对我来说意义不大。但它可以用来增加一对中的第一个数字:
Prelude Control.Arrow> :t first (+1)
first (+1) :: (Num b) => (b, d) -> (b, d)
和
Prelude Control.Arrow> :t (&&&)
(&&&) :: (Arrow a) => a b c -> a b c' -> a b (c, c')
Prelude Control.Arrow> :t (pred &&& succ)
(pred &&& succ) :: (Enum b) => b -> (b, b)
有人可以解释一下这是如何运作的吗?
答案 0 :(得分:2)
第一个箭头采用普通箭头,并更改它以对元组中的第一个元素执行操作,并将结果输出为箭头
a b c -> a (b, d) (c, d)
a b c -- is the input arrow, an operation that maps type b to c
a (b, d) (c, d) -- is the output arrow, an operation that maps a tuple (b, d) to (c, d)
它使用d作为元组中未知第二类型的虚拟
&安培;&安培;&安培;取两个带有相同输入的箭头并创建一个箭头,该箭头接受该输入,将其复制到元组中并运行元组的每个部分上的一个箭头,返回更改的元组。
对于一些实用的教程,请查看: http://www.vex.net/~trebla/haskell/hxt-arrow/lesson-0.xhtml
答案 1 :(得分:2)
Arrow (->)
有一个实例。所以
(&&&) :: (Arrow a) => a b c -> a b c' -> a b (c,c')
有实例化
(&&&) :: (->) b c -> (->) b c' -> (->) b (c,c')
或者用更传统的符号写成,
(&&&) :: (b -> c) -> (b -> c') -> (b -> (c,c'))
其余的应该从那开始。
我在(***)
实例上一直使用箭头函数(尤其是(&&&)
和(->)
) 。我对Arrow
的任何其他实例使用这些组合器非常罕见。因此,每当您看到a b c
时,请考虑从b
到c
的“(广义)函数”,它也适用于常规函数。
答案 2 :(得分:1)
我不久前做过关于如何在纯函数上使用箭头函数的博客文章
http://blog.romanandreg.com/post/2755301358/on-how-haskells-are-just-might-just-be-function
我尝试以非常简单和详细的方式介绍所有基本的箭头方法。
干杯。