3

aにIO Intラップされた があり、スタック モナドで使用したいStateT MyState値があるとします。State MyState Intこの内的な意味でそれを持ち上げるにはどうすればよいですか?私はすでに外側のモナドに持ち上げる必要がある内部と互換性のあるものを使用することを知っていますliftliftIO、今は逆の問題があります: 値はすでに外側のモナドにありますが、内側のモナドにはありません。

例えば:

checkSame :: State MyState a -> IO a -> StateT MyState IO Bool
checkSame sim real = do
  rres <- liftIO real
  sres <- ??? sim 
  return $ rres == sres

状態を「取得」し、それを runState に手で押し込み、すべてを再度ボックス化する必要がありますか、それともこれを行う一般的な方法はありますか?

StateT MyState IO aところで、その sim パラメータは IO とは何の関係もない一連のステートフル関数であるため、回避できる場合はそれらすべてを返すことに少し気が進まないのです。

4

1 に答える 1

7

次の 2 つのオプションがあります。

  1. モナド射を見つけます。これは、多くの場合、適切なライブラリを見つけることの問題です。この場合、ホイスト一般化を一緒に行うと、必要な場所に移動できます。
  2. Stateアクションをより多態的にします。これは一般的に使用されるものであり、推奨されるものです。これは、パート 1 のモーフィズムを事前に適用することになりますが、mtlライブラリには、それを簡単にするために既に多くの機械が配置されています。ここでの考え方は、Stateアクションをgetput、およびのみで記述した場合modify、 type の代わりに typeState s aを指定できるということです。

    MonadState s m => m a
    

    State s aその後、呼び出しサイトで、 と の両方を含む、これに適したモナドを選択できますStateT s IO a。さらに、それは type に特化しているため、それ自体が実行できなかったようなことは何もState s a実行しないことを確認でき、同じ動作保証が得られます。IOState s a

于 2014-11-29T19:30:00.857 に答える