ここに少しサンプルコードがあります
foo :: a -> Identity (Maybe a)
foo a = do
maybeStuff <- getStuffSometimes a
return $ case maybeStuff of -- this "case" stuff is the kind
Just stuff -> Just $ getStuffAlways stuff -- of code I'd expect the Maybe
Nothing -> Nothing -- monad to help with
getStuffSometimes :: a -> Identity (Maybe a)
getStuffSometimes a = return $ Just a
getStuffAlways :: a -> Identity a
getStuffAlways = return
-- ERROR (on the return statement of the do block)
-- Expected type: Identity (Maybe a)
-- Actual type: Identity (Maybe (Identity a))
私がやろうとしていることは少し不明確かもしれないので、ここにより詳細な説明があります:
興味深いものはすべて、計算コンテキスト/コンテナー (この場合は
Identity
、デモンストレーションのために ) にラップされています。私の実際のコードでは、もちろん別のモナドがあります。foo
getStuffSometimes
型の何かを取り、コンテキストでラップされたa
を返すことになっています。つまり、(計算が成功したか、または(計算が失敗しました) を返します。Maybe a
Identity (Just a)
Identity Nothing
getStuffAlways
は決して失敗しない計算であり、常に を返しますIdentity a
。私がしたい
foo
:- 失敗可能な計算を実行する
- 失敗可能な計算が失敗した場合、失敗します (Nothing を使用)
- 失敗可能な計算が成功した場合は、それを getStuffAlways でバインドし、戻ります
Just (result of getStuffAlways to the result of #1)
これは Monad Transformers の使用例ですか? 私の場合、実際のモナドは少し複雑で、IO の上に私のライブラリによって与えられた複数のトランスフォーマーのスタックであり、この状況でそれを機能させる方法が完全にはわかりません (別の質問で尋ねます変圧器を使わなければならないということになります)
ファローアップ:
実生活では、次のようなものがあります。
foo :: a -> Identity (a, Maybe a)
foo a = do
firstPart <- getStuffAlways a
maybeStuff <- getStuffSometimes a
secondPart <- case maybeStuff of
Just stuff -> Just $ getStuffAlways stuff
Nothing -> Nothing
return (firstPart, secondPart)
この場合、スタックを構築する最良の方法は何でしょうか?