6

ListT私は現在、モナド変換子を多用するプロジェクトを書いています。プレーンリストを使用する場合、非決定性の実装は非常に簡単です。ただし、コードをに変換する必要ListTがあると、はるかに複雑になります1

[a]簡単な例として、からへの変換には、ListT a実際には2つの関数を作成する必要があります。

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

シンプルですが、まだそこにないのには驚きました。

質問:

  • モナド変換子が必要な非決定性を処理するためのより良い方法はありますか?
  • リスト間をきれいに行き来するためのテクニック/ライブラリはありListTますか?

1正確な理由は非常に複雑なので、あまり詳しく説明したくありません。

4

2 に答える 2

6

このためのライブラリはないと思います。conv結局のところ、は信じられないほど単純な関数であり、その逆はただrunListTです。

convliftMaybeを使用するときによく望まれるものと似ていますMaybeT

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

の線に沿って名前を付けることをお勧めしliftListます。1

非決定性のためのより良いモナド変換子に関する限り、いくつかの有用な操作を備えた継続ベースのバックトラッキング論理モナドであるOlegの変換子に基づくlogictパッケージを調べることをお勧めします。ボーナスとして、はのインスタンスであるため、これらの操作はリストでも機能します。LogicT[]MonadLogic


1conv興味深いことに、とのパターンを一般化する関数を定義できます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

これはおそらくあなたのコードをかなり混乱させるでしょう、それで私はそれを使うことをお勧めしません:)

于 2012-02-09T16:40:02.033 に答える
0

私はこれに似た何かを考えていたので、数ヶ月後にこの質問に出くわしました。だから私は次のことを思いついた:

{-# 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

これまでのところ良いです—そして/ペアjoinTの私の方法はそれがehirdのものと関係があるように見えます。ListT[]choose

しかし、これに伴う問題は、モナド変換子と、その動作がベースモナドに与えられるモナドとの間に実際には均一なインターフェースがないことです。とがMaybeT :: m (Maybe a) -> MaybeT m aありますListT :: m [a] -> ListT m aが、OTOHがありStateT :: (s -> m (a, s)) -> StateT s m aます。これを回避する方法があるかどうかはわかりません—確かに必要です

于 2012-08-07T08:19:38.867 に答える