Эквивалент стрелки mapM?

Я пытаюсь залезть и работать со стрелами, и мне сложно. У меня есть контекст, где мне нужен Arrow [a] [b], и я хочу написать Arrow a b и отобразить/упорядочить его внутри стрелки, a la mapM. В частности, стрелка представляет собой Hakyll Compiler, но я не думаю, что это имеет большое значение для ответа.

Учитывая стрелку

myInnerArrow :: Arrow a => a b c

Как я могу поднять это в стрелку

myOuterArrow :: Arrow a => a [b] [c]

?

Я просмотрел базовую библиотеку, особенно в Data.List и Control.Arrow, но я не могу найти ничего похожего на то, что она выполнит эту работу. Существует ли это под именем, которого я не ожидаю? Предоставляется ли она какой-либо другой библиотекой? Невозможно ли писать по какой-либо причине?

Ответы

Ответ 1

Вы не можете без выбора. Функция подъема будет иметь следующий тип:

mapA :: (ArrowChoice a) => a b c -> a [b] [c]

Самый простой способ реализовать - использовать обозначение proc:

mapA c =
    proc xs' ->
        case xs' of
            [] -> returnA -< []
            (x:xs) -> uncurry (:) ^<< c *** mapA c -< (x, xs)

Неподтвержденный код, но он должен работать. Обратите внимание, однако, что функция, которая генерирует, будет очень медленной. Я рекомендую написать эту функцию отображения для вашей стрелки.