Фон
Я проходил через John Hughes Программирование со стрелками, и я чувствовал, что у меня все прямо в голове, пока следующее пример использования 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]])передается в нижнюю часть -
(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]]?