免费的MonadPlus定义为
data Free f a = Pure a | Free (f (Free f a)) | Plus [Free f a]
已在免费4.6中删除,并带有以下注释(更改日志):
已删除
Control.MonadPlus.Free
。改用FreeT f []
,结果是中规中矩。
问题是什么,特别是哪些法律不成立?
根据错误跟踪器中的这个问题,旧定义不遵守关联定律。
虽然我对这些事情知之甚少,但我怀疑另一个问题是冗余:
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
IE
Monoid a
而不是任意函数[a] -> a
iter
MonadPlus m
的任意函数[m a] -> m a
。iterM
我的猜测是它被删除(而不是固定)只是因为在FreeT f []
给出等效表示时不值得保留。