ほとんどのモナド関数は純粋な引数を取り、モナド値を返します。ただし、モナド引数も必要なものがいくつかあります。たとえば、次のようになります。
mplus :: (MonadPlus m) => m a -> m a -> m a
finally :: IO a -> IO b -> IO a
forkIO :: m () -> m ThreadId
-- | From Control.Monad.Parallel
forkExec :: m a -> m (m a)
それらのそれぞれが異なる問題を引き起こしているようで、フリーモナドを使用してそのようなアクションをエンコードする一般的な方法を把握できません。
両方
finally
のforkIO
問題は、モナド引数が結果とは異なる型であることです。しかし、無料の場合は、のみをエンコードするIO a
のようなエンコーディング タイプの型変数に置き換えられるため、それらが同じタイプである必要があります。data MyFunctor x = Finally x x x
IO a -> IO a -> IO a
著者が最初に実装するために使用するHaskellコードの 33 行のゼロから協調スレッドへ
Fork next next
cFork :: (Monad m) => Thread m Bool cFork = liftF (Fork False True)
そして、それを使用して実装します
fork :: (Monad m) => Thread m a -> Thread m ()
入力と出力の型が異なります。しかし、これが何らかのプロセスを使用して導き出されたものなのか、それともこの特定の目的のために機能するアドホックなアイデアなのかはわかりません。
mplus
特に紛らわしい: 単純なエンコーディングdata F b = MZero | MPlus b b
配布され
>>=
、提案されたより良い実装はより複雑です。また、 free のネイティブ実装が freeからMonadPlus
削除されました。freerでは、追加することで実装されます
data NonDetEff a where MZero :: NonDetEff a MPlus :: NonDetEff Bool
MPlus
NonDetEff Bool
の代わりにあるのはなぜNonDetEff a a
ですか?CoYoneda functorFree
を使用する以外に、データ型を functor にする必要がある で動作させる方法はありますか?forkExec
どうやって進めばいいのかわからないからです。