具有多个通道的功能组合
模糊地讲, Arrow
是一类构成类似函数的态射,具有连续组合和并行组合。虽然最有趣的是函数的泛化,但 Arrow (->)
实例本身已经非常有用。例如,以下功能:
spaceAround::Double -> [Double] -> Double
spaceAround x ys = minimum greater - maximum smaller
where (greater, smaller) = partition (>x) ys
也可以用箭头组合器编写:
spaceAround x = partition (>x) >>> minimum *** maximum >>> uncurry (-)
这种组合最好用图表可视化:
──── minimum ────
╱ * ╲
──── partition (>x) >>> * >>> uncurry (-) ───
╲ * ╱
──── maximum ────
这里,
-
该
>>>
运算符只是一个翻转普通.
组成运算符的版本(也有对构成从右到左一<<<
版)。它将数据从一个处理步骤传输到下一个处理步骤。 -
外出的
╱
╲
表示数据流被分成两个通道。就 Haskell 类型而言,这是通过元组实现的:partition (>x) :: [Double] -> ([Double], [Double])
在两个
[Double]
通道中分流,而uncurry (-) :: (Double,Double) -> Double
合并了两个
Double
频道。 -
***
是并行 † 组合算子。它允许maximum
和minimum
在不同的数据通道上独立运行。对于函数,此运算符的签名是(***) :: (b->c) -> (β->γ) -> (b,β)->(c,γ)
† 至少在 Hask 类别中(即在 Arrow (->)
实例中),f***g
实际上不会在不同的线程上并行计算 f
和 g
。不过,理论上这是可能的。