2

mappend概要: Writer モナドを使用しているときに、状態を失うことなくの 2 つの異なるバージョンを切り替えられるようにしたいと考えています。

いくつかの状態を追跡するために、2 つのブール値フラグを使用します。

data Flags = F Bool Bool

Monoid次に、フラグを組み合わせる方法が異なる2 つのインスタンスを定義しmappendます。

newtype XFlags = XF Flags

instance Monoid XFlags where
  mempty = XF (F True False)
  (XF (F s0 c0)) `mappend` (XF (F s1 c1)) = XF (F (s0 && s1)
  (c0 || c1 || not (s0 || s1)))

newtype SFlags = SF Flags

instance Monoid SFlags where
  mempty = SF (F True False)
  (SF (F s0 c0)) `mappend` (SF (F s1 c1)) = SF (F (s0 && s1) (c0 || c1))

これで、異なるフラグ処理を持つ 2 つの Writer モナドを持つことができます:

type XInt = WriterT XFlags Identity Int
type SInt = WriterT SFlags Identity Int

これで、次のような操作を実行できます。

xplus :: XInt -> XInt -> XInt
xplus = liftM2 (+)

splus :: SInt -> SInt -> SInt
splus = liftM2 (+)

次のような式を作成したいと思います。

foo = splus (return 1) (xplus (return 2) (return 3))

そのためには、フラグを失うことなく、できれば ( を使用してrunWriter) モナドをアンラップすることなく、2 つの間で変換できる必要があります。この部分は私が把握していません。モナドトランスフォーマーを使用してライターをネストできるように少し見えますが、ここで直接適用できるかどうかはわかりません。このようなものを実装するための最良の方法について、いくつかのガイダンスをいただければ幸いです。

4

1 に答える 1