Control.MonadPlus.Free 出了什么问题?

What was wrong with Control.MonadPlus.Free?

free MonadPlus定义为

data Free f a = Pure a | Free (f (Free f a)) | Plus [Free f a]

已在 free 4.6 中删除,并带有以下注释 (changelog):

Removed Control.MonadPlus.Free. Use FreeT f [] instead and the result will be law-abiding.

问题出在哪里,特别是哪些法律不成立?

根据错误跟踪器中的 issue,旧定义不遵守关联律。


虽然我对这些事情知之甚少,但我怀疑另一个问题是冗余:

Pure a
Plus [Pure a]
Plus [Plus [Pure a]]
...

似乎都代表同一件事。自由结构通常应该是唯一的。有时它们不能被唯一表示(例如,自由阿贝尔群),但在可能的情况下它们应该是。

实际上,我认为建议的替代方案也存在同样的问题,尽管使用 NonEmpty 而不是 [] 可能可以修复它。因此,此更改可能只是从库中删除多余内容的问题。

我认为表示本身没问题,并且可以通过更改这些方法签名来补救合法性

iter :: Functor f => (f a -> a) -> ([a] -> a) -> Free f a -> a
iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> ([m a] -> m a) -> Free f a -> m a

iter :: (Functor f, Monoid a) => (f a -> a) -> Free f a -> a
iterM :: (MonadPlus m, Functor f) => (f (m a) -> m a) -> Free f a -> m a

  • 使用 Monoid a 代替 任意 函数 [a] -> a in iter;
  • iterM.
  • 中使用MonadPlus m代替任意函数[m a] -> m a

我的猜测是它被删除(而不是修复)只是因为当 FreeT f [] 给出等效表示时不值得保留。