Манипулирование бесплатными монадами в Purescript

Почему Control.Monad.Free в purescript-free скрывает структуру данных "представление" FreeView и связанные операторы toView и т. д.?

С обычной формулировкой Свободной Монады -

data Free f a = Pure a | Free (f (Free f a))

И учитывая функтор, такой как -

data TeletypeF a = PutStrLn String a | GetLine (String -> a)

Я могу написать простой (хотя и уродливый) код, чтобы свернуть цепочку вызовов PutStrLn, например так:

collapseChained :: Free TeletypeF a -> Free TeletypeF a
collapseChained (Free (PutStrLn s1 (Free (PutStrLn s2 c)))) = Free PutStrLn (s1 ++ s2) c
collapseChained f = f

Возможно ли что-то эквивалентное collapseChained с использованием функций, экспортируемых Purescript Control.Monad.Free, без использования каких-либо фактических конструкторов данных?


person Anupam Jain    schedule 04.01.2016    source источник


Ответы (1)


Какое-то время я пытался сделать это с помощью runFreeM и т.п., но безуспешно, так что нет, я не думаю, что такое преобразование возможно напрямую.

Обычная формулировка Free, которую вы упомянули, не подходит для использования в PureScript, поскольку ее нельзя сделать безопасной для стека, поэтому, к сожалению, прямое манипулирование деревом скрыто. Конструкторы теперь вообще не экспортируются, так как мы используем внутренние небезопасные приведения, чтобы сделать возможной реализацию в стиле Отражение без угрызений совести.

Ранее у нас был слегка другая реализация без принуждения, которая была похожа на scalaz Free, так как она также требует реализации, безопасной для стека, но я думаю, что у нее была бы такая же проблема.

Возможно, если бы мы открыли больше внутренних элементов (fromView, toView и т. д.), это было бы возможно, но все же это менее приятно, чем метод прямого сопоставления с образцом, и я думаю, что их раскрытие может иметь проблемы с безопасностью.

person gb.    schedule 05.01.2016
comment
Ага, как я и боялся :) Меня меньше волнует, приятно ли это, и больше то, возможно ли это вообще. В другом фрагменте кода, который у меня есть на Haskell, я сопоставляю шаблон в конструкторе Free, чтобы разворачивать лук по одному слою за раз. Похоже, что это невозможно и с текущей формулировкой purescript :( - person Anupam Jain; 06.01.2016