[英]How does mapA work with a Stream Function Arrow in Haskell?
我一直在阅读约翰·休斯的“ 箭头编程” ,我觉得直到下面的使用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
。 (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]]
?
我发现这些例子很难理解。 在此示例中有两个列表,外部列表是箭头操作的流,而内部列表是mapA映射的内容。 考虑一个更简单的例子,所以我们现在可以忽略递归的情况。 特定
runSF (mapA (delay 0)) [[1], [2]]
我们看到了第一步
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]] ^ | [[], []]
关键是要认识到用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
对不起,我不能画得更好。 实际上, mapA
给出了输入列表的转置视图,因此您可以将mapA (delay 0)
视为像transpose . map (init . (0:)) . transpose
一样操作transpose . map (init . (0:)) . transpose
transpose . map (init . (0:)) . transpose
transpose . map (init . (0:)) . transpose
,因为init . (0:)
init . (0:)
是delay
的定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.