3

私が解決したいタスクから始めましょう、おそらく私は間違った方向に進んでいます。私はおもちゃのプロジェクトにSnapフレームワークを使用していますが、主なものはSnapモナドの下で機能することです。その上に自分の状態を追加する必要があります。私はモナド変換子を使用します:

type SnapApp a = StateT AppState Snap a

これは、モジュールで定義されていますBase。他のモジュールで必要なので、エクスポートする必要があります。

module Base
  ( ..
  , SnapApp
  ) where

SnapAppこれは良いことですが、状態の属性を設定するための複雑な処理があるため、状態モナドであるモジュールをエクスポートしないようにします。たとえば、セッション。変更されたときにファイルを書き込まなければならないので、変更されたセッションgetよりも間違っているのでput、特別な関数を呼び出す必要があります。だから、私newtypeはデータをエクスポートするコンストラクタではなく、それを使用することを隠します:

newtype SnapApp a = SnapApp (StateT AppState Snap a)

セッションなどを変更するための関数を使用してクラスのインスタンスにしました。しかし、問題が発生します。Monad新しいためにクラスやその他のインスタンスを失いましSnapAppた。そして、私は実装に固執しています>>=

instance Monad SnapApp where
    return = SnapApp . return
    mx >>= fm = -- HOW?

ありがとうございました!

4

2 に答える 2

16

タイプがあなたを導きます。あなたが必要

(>>=) :: SnapApp a -> (a -> SnapApp b) -> SnapApp b

あなたが持っている

(>>=) :: StateT AppState Snap a -> (a -> StateT AppState Snap b) -> StateT AppState Snap b

変換する必要があります:

  • SnapApp aへの引数StateT AppState Snap a
  • a -> SnapApp bへの引数a -> StateT AppState Snap b
  • StateT AppState Snap bに結果SnapApp b

1) パターン マッチングを使用します。定義:

fromSnapApp (SnapApp x) = x

2) 関数a -> SnapApp bを構成し、SnapApp b -> StateT AppState b

3) 使用SnapApp

最終結果:

x >>= f = SnapApp (fromSnapApp x >>= (fromSnapApp . f)) 

また:

SnapApp x >>= f = SnapApp (x >>= (fromSnapApp . f)) 

これを書く必要はありません。GeneralizedNewtypeDeriving拡張機能を有効にすると、GHC はインスタンスを派生できます。

newtype SnapApp a = SnapApp (StateT AppState Snap a) deriving (Monad)
于 2012-05-26T10:01:08.600 に答える
3

この状態管理は、まさに私たちがスナップレットで処理できるように設計したものです。StateT s Snap私たちの Handler モナドは、実際には、利便性のためにいくつかの追加機能が組み込まれた単なる newtype ラッパーです。回避しようとしている MonadState インスタンスを公開していますが、状態タイプをモジュールにカプセル化し、アクセサーをエクスポートしないことでこれを処理できます。複雑な属性処理をすべて実行する目的の Handler 関数のみをエクスポートできます。

于 2012-05-27T03:30:26.787 に答える