これはMaybeT
monad transformerを通じて達成することができます:
GHCi> import Control.Monad.Trans.Maybe
GHCi> :t \f m -> runMaybeT (MaybeT m >>= MaybeT . f)
\f m -> runMaybeT (MaybeT m >>= MaybeT . f)
:: Monad m => (a1 -> m (Maybe a)) -> m (Maybe a1) -> m (Maybe a)
import Control.Monad.Trans.Maybe
-- Making it look like your definition, for the sake of comparison.
ioMaybeApply :: (a -> IO (Maybe b)) -> IO (Maybe a) -> IO (Maybe b)
ioMaybeApply f ioMaybeA = runMaybeT $ do
a <- MaybeT ioMaybeA
MaybeT (f a)
あなたが複数の場所でこのパターンを使用している場合、それはおそらくa -> MaybeT IO b
にごa -> IO (Maybe b)
の機能を変更することが報われる - あなたは特殊用途の機能の代わりに(>>=)
および/またはシームレスなブロックを使用することができます。一方、これがちょうど一回限りのものであれば、MaybeT
を使用することは過度のものであると合理的に考えるかもしれません。その場合、実装は完璧です。
(必ずしも何かにはなりません営巣2つのモナドとして、Functor
とApplicative
インスタンスを持つCompose
と呼ばれる、ネストされたファンクタのための汎用的なラッパーがありながら、それはMonad
インスタンスを持っていないことを言及する価値があります法律であるMonad
インスタンスを指定することができますが、通常は、動作する各組み合わせに合わせてモナド変圧器を使用しています)
しかし、おそらく:: b - >(a - > b) - > bは 'IO'モナドではありませんか? –
@WillemVanOnsem私のコードでは、 'maybe'は' return Nothing'( 'IO(Maybe b)'型)または 'f'(' IO(Maybe b) ')の戻り値のいずれかを返します。 –