具有多个通道的功能组合
模糊地讲, 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。不过,理论上这是可能的。