jul*_*icz 6 monads haskell list non-deterministic monad-transformers
我目前正在编写一个项目,我大量使用ListT
monad变换器.使用普通列表时,实现非确定性很容易.但是,一旦我必须将我的代码转换为ListT
,它就会变得更加复杂1.
举个简单的例子:转换[a]
为ListT a
实际需要组成两个函数:
conv :: (Monad m) => [a] -> ListT m a
conv = ListT . return
Run Code Online (Sandbox Code Playgroud)
虽然很简单,但我很惊讶它还没有出现.
问题:
ListT
?1确切的原因非常复杂,所以我真的不想详细说明.
我不认为这有任何图书馆; conv
毕竟,这是一个非常简单的功能,而另一种方式就是runListT
.
conv
类似于liftMaybe
使用时经常需要的MaybeT
:
liftMaybe :: (Monad m) => Maybe a -> MaybeT m a
liftMaybe = MaybeT . return
Run Code Online (Sandbox Code Playgroud)
我建议将其命名为liftList
.1
至于一个更好的monad变换器用于非确定性,我建议看一下基于Oleg 变换器的logict包LogicT
,这是一个基于延续的回溯逻辑单元,带有一些有用的操作.作为奖励,因为[]
是一个实例MonadLogic
,这些操作也在列表上工作.
1有趣的是,我们可以定义可以推广的图案的函数conv
和liftMaybe
:
import Data.Foldable (Foldable)
import qualified Data.Foldable as F
choose :: (Foldable t, MonadPlus m) => t a -> m a
choose = F.foldr (\a b -> return a `mplus` b) mzero
Run Code Online (Sandbox Code Playgroud)
这可能会让你的代码很混乱,所以我不推荐使用它:)