我一直在阅读约翰·休斯的" 箭头编程",我觉得直到下面的使用mapA的例子我才能直截了当:
>runSF (mapA (delay 0)) [[1,2,3],[4,5,6],[7,8,9]]
[[0,0,0],[1,2,3],[4,5,6]]
Run Code Online (Sandbox Code Playgroud)
其中runSF从StreamFunction箭头中提取流函数,定义为:
newtype SF a b = SF {runSF :: [a]->[b]}
Run Code Online (Sandbox Code Playgroud)
延迟定义为:
delay x = SF (init . (x:))
Run Code Online (Sandbox Code Playgroud)
SF是ArrowChoice的一个实例(声明mapA),因此是Arrow的一个实例.
mapA :: arr a b -> arr [a] [b]
delay :: SF a b
Run Code Online (Sandbox Code Playgroud)
这样delay只需要用它的第一个参数预先设定它的第二个参数.
因此,mapA (delay 0)应该返回一个获取[[a]]并返回的SF箭头[[b]]
mapA (delay 0) :: SF [[a]] [[b]]
Run Code Online (Sandbox Code Playgroud)
我希望这会产生的"电路"是:

数字标记过程的一部分:
list x,listcase都会发出Right(x, xs).对于空列表,listcase将发出Left(),终端案例.Right将传递到下半部分.标记的值Left将传递给const[],这实质上停止了迭代.(x, xs),x将传递给(delay 0),同时xs将传递回去listcase.(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]]?
我发现这些例子很难理解.在此示例中有两个列表,外部列表是箭头操作的流,而内部列表是mapA映射的内容.考虑一个更简单的例子,所以我们现在可以忽略递归的情况.特定
runSF (mapA (delay 0)) [[1], [2]]
Run Code Online (Sandbox Code Playgroud)
我们看到了第一步
listcase箭头管道输入为我们提供输出
[Right (1, []), Right (2, [])].每对中的第一个元素被馈送到delay 0箭头,而第二个元素被反馈到mapA f.[1, 2] => delay 0和[[], []] => mapA f.饲养[1,2]到delay 0给出结果[0, 1],并喂空名单mapA f产生了更多的空列表
[[], []].这两个结果被馈送到arr (uncurry (:)),其行为类似zipWith (:),因为这些函数都映射到列表上,因此它以元素方式连接两个输入列表.
[0, 1]
|
v
arr (uncurry (:)) => [ 0:[], 1:[] ] == [[0], [1]]
^
|
[[], []]
Run Code Online (Sandbox Code Playgroud)关键是要认识到构造的所有东西都在arr内部列表集上运行,因此运行初始输入arr listcase
不会产生Right ([1,2,3],[[4,5,6],[7,8,9]]),但是
[Right (1, [2, 3]), Right (4, [5,6]), Right (7, [8,9])].这是我尝试在图表中绘制它.
[Right (1, [2, 3]), Right (4, [5,6]), Right (7, [8,9])]
=======================================================
| [1, 4, 7] +-----------+ [0, 1, 4]
+----------+ | +----=--------->| delay |-----=------|
| listcase |---=------>| +-----------+ | +-------------------+
+----------+ | +-->| arr (uncurry (:)) |---> [[0,0,0],[1,2,3],[4,5,6]]
| | +-------------------+
| +-----------+ |
+-------=------>| mapA f |------=-----|
| +-----------+ |
| |
[[2,3],[4,5],[6,7]] [[0,0], [2,3],[4,5]]
* what will be
returned if you
trace it through
Run Code Online (Sandbox Code Playgroud)
对不起,我不能画得更好.实际上,mapA给出了输入列表的转置视图,因此您可以将其mapA (delay 0)视为操作
transpose . map (init . (0:)) . transpose,因为init . (0:)是定义delay.
| 归档时间: |
|
| 查看次数: |
321 次 |
| 最近记录: |