【发布时间】:2014-04-13 20:32:26
【问题描述】:
背景
我一直在浏览 John Hughes 的Programming with Arrows,我觉得我的一切都在我的脑海中,直到以下使用 mapA 的示例:
>runSF (mapA (delay 0)) [[1,2,3],[4,5,6],[7,8,9]]
[[0,0,0],[1,2,3],[4,5,6]]
其中 runSF 从 StreamFunction 箭头中提取流函数定义为:
newtype SF a b = SF {runSF :: [a]->[b]}
而延迟定义为:
delay x = SF (init . (x:))
SF 是 ArrowChoice 的一个实例(它声明了 mapA),因此也是一个 Arrow 的实例。
我的理解
mapA :: arr a b -> arr [a] [b]
delay :: SF a b
这样delay 只需将其第二个参数添加到第一个参数之前。
因此,mapA (delay 0) 应该返回给我们一个 SF 箭头,它接受 [[a]] 并返回 [[b]]
mapA (delay 0) :: SF [[a]] [[b]]
我希望这会导致的“电路”是:
数字标记流程的各个部分:
- 对于任何非空的
list x,listcase将发出Right(x, xs)。对于空列表,listcase将发出Left(),即终端情况。 - 标记为
Right的值将传递到下部。标记为Left的值将传递给const[],这实际上会停止迭代。 - 输入
(x, xs),x将被传递给(delay 0),而xs将被传递回listcase。 - 3 的输出将是
(z, zs),它被传递给uncurry (:),后者将元组重新加入到列表中。
这是我对流程的理解,输入[[1,2,3],[4,5,6],[7,8,9]]:
-
第一关
Right ([1,2,3],[[4,5,6],[7,8,9]])-
([1,2,3], [[4,5,6],[7,8,9]])被传递到下部 -
在
[1,2,3]上调用(delay 0),产生[0,1,2]。[[4,5,6],[7,8,9]]被传回listcase
-
第二遍
Right ([4,5,6], [[7,8,9]])-
([4,5,6], [[7,8,9]])被传递到下部 -
在
[4,5,6]上调用(delay 0),产生[0,4,5]。[[7,8,9]]被传回listcase
-
第三遍
Right ([7,8,9], [])-
([7,8,9], [])被传递到下部 -
在
[7,8,9]上调用(delay 0),产生[0,7,8]。[]被传回给listcase。
-
第四关
-
Left (),掉在地上。
-
此时,我们进入第 4 部分,它获取 3 的输出并将它们连接在一起。我们基本上构建了以下操作:
[0,1,2] : [[0,4,5] : [[0,7,8] : []]]
这会给我们[[0,1,2],[0,4,5],[0,7,8]]。
我的困惑
显然,我上面的流程是错误的。
调用runSF (mapA (delay 0)) [[1,2,3],[4,5,6],[7,8,9]] 是如何产生[[0,0,0],[1,2,3],[4,5,6]] 的?
【问题讨论】:
-
好吧,显然我的理解是错误的,因为延迟的类型是 SF。不是函数本身。