在 Purescript 中操作自由 Monad

Manipulating Free Monads in Purescript

为什么 purescript-free 中的 Control.Monad.Free 隐藏了 "view" 数据结构 FreeView 和相关运算符 toView 等?

使用 Free Monad 的常用公式 -

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

并给定一个 Functor,例如 -

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

是否可以使用 Purescript Control.Monad.Free 导出的函数,而不使用任何实际的数据构造函数,实现与 collapseChained 等价的东西?

我尝试了一段时间用 runFreeM 之类的方法来做这个但是没有成功,所以不,我认为不可能像这样直接转换。

您提到的 Free 的常用公式不适合在 PureScript 中使用,因为它不能使堆栈安全,因此不幸的是,对树的直接操作被掩盖了。现在根本不导出构造函数,因为我们正在使用内部不安全的强制转换来实现 Reflection without Remorse.

的样式

我们之前有一个 slightly different implementation 没有强制转换,类似于 scalaz Free,因为它也需要堆栈安全实现,但我认为这也会有同样的问题。

也许如果我们暴露更多的内部结构(fromViewtoView 等)这是可能的,但它仍然不如直接模式匹配方法令人愉快,我认为暴露那些可能存在安全问题。