如何在列表和ListT monad变换器之间进行干净的转换?

jul*_*icz 6 monads haskell list non-deterministic monad-transformers

我目前正在编写一个项目,我大量使用ListTmonad变换器.使用普通列表时,实现非确定性很容易.但是,一旦我必须将我的代码转换为ListT,它就会变得更加复杂1.

举个简单的例子:转换[a]ListT a实际需要组成两个函数:

conv :: (Monad m) => [a] -> ListT m a
conv = ListT . return
Run Code Online (Sandbox Code Playgroud)

虽然很简单,但我很惊讶它还没有出现.

问题:

  • 有没有更好的方法来处理需要monad变换器的非确定性?
  • 是否有任何技术/库可以在列表之间来回干净地进行转换ListT

1确切的原因非常复杂,所以我真的不想详细说明.

ehi*_*ird 6

我不认为这有任何图书馆; 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 变换器的logictLogicT,这是一个基于延续的回溯逻辑单元,带有一些有用的操作.作为奖励,因为[]是一个实例MonadLogic,这些操作也在列表上工作.


1有趣的是,我们可以定义可以推广的图案的函数convliftMaybe:

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)

这可能会让你的代码很混乱,所以我不推荐使用它:)