如何干净地转换列表和ListT monad变换器?

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

作为一个简单的例子:从[a]转换到ListT a实际上需要编写两个函数:

conv :: (Monad m) => [a] -> ListT m a
conv = ListT . return

虽然很简单,但我感到惊讶,它并不在那里。

问题:

  • 是否有更好的方法来处理需要单子变压器的非确定性?
  • 是否有任何技术/库在清单和ListT之间来回转换?

  • 1确切的原因相当复杂,所以我不想在此详细阐述。


    我不认为有这样的图书馆; conv是一个令人难以置信的简单函数,毕竟,其他方法只是runListT

    conv类似于liftMaybe使用时通常需要MaybeT

    liftMaybe :: (Monad m) => Maybe a -> MaybeT m a
    liftMaybe = MaybeT . return
    

    我建议将其命名为liftList .1

    就非确定性而言,一个更好的monad变换器,我建议看看基于Oleg的LogicT变换器的逻辑程序包,它是一种基于延续的回溯逻辑单元,带有一些有用的操作。 作为奖励,由于[]MonadLogic一个实例, MonadLogic这些操作也可以在列表中使用。


    1有趣的是,我们可以定义一个函数来概括convliftMaybe的模式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
    

    这可能会让你的代码非常混乱,所以我不建议使用它:)


    几个月后我刚刚发现了这个问题,因为我想知道类似这样的事情。 所以我想出了以下几点:

    {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
    
    import Control.Monad.Trans.Class
    import Control.Monad.Trans.Maybe
    import Control.Monad.Trans.List
    
    
    -- | Minimal implementation: either joinLift or joinT
    class (MonadTrans t, Monad m) => MonadTransJoin t m | m -> t, t -> m where
        joinLift :: (Monad m', Monad (t m')) => m' (m a) -> t m' a
        joinLift = joinT . lift
    
        joinT :: (Monad m', Monad (t m')) => t m' (m a) -> t m' a
        joinT = (>>= (joinLift . return))
    
    
    instance MonadTransJoin MaybeT Maybe where
        joinLift = MaybeT
        joinT = (>>= maybe mzero return)
    
    instance MonadTransJoin ListT [] where
        joinLift = ListT
        joinT = (>>= foldr mcons mzero)
            where mcons x xs = return x `mplus` xs
    

    到目前为止这么好 - 我的ListT / []对的joinT方法看起来好像与ehird的choose

    但是问题在于,monad变换器和monad的基本monad行为之间实际上没有统一的接口。 我们有MaybeT :: m (Maybe a) -> MaybeT maListT :: m [a] -> ListT ma ,但是OTOH我们有StateT :: (s -> m (a, s)) -> StateT sma 。 我不知道是否有办法解决这个问题 - 它肯定需要

    链接地址: http://www.djcxy.com/p/77361.html

    上一篇: How to cleanly convert between lists and ListT monad transformers?

    下一篇: What is the name of this Monad Stack function?