背景
我一直在阅读 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)
应该返回给我们一个接受[[a]]
和返回的 SF 箭头[[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]])
被传递到下部(delay 0)
被调用[1,2,3]
,导致[0,1,2]
.[[4,5,6],[7,8,9]]
被传回listcase
第二遍
Right ([4,5,6], [[7,8,9]])
([4,5,6], [[7,8,9]])
被传递到下部(delay 0)
被调用[4,5,6]
,导致[0,4,5]
.[[7,8,9]]
被传回listcase
第三关
Right ([7,8,9], [])
([7,8,9], [])
被传递到下部(delay 0)
被调用[7,8,9]
,导致[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]]
?