Есть функции с подписями вроде:
a -> IO (m b)
b -> IO (m c)
c -> IO (m d)
Как приковать их в
a -> IO (m d)
В родах l, вы, возможно, не сможете. Например, если m
- Const
, я не уверен, что это даже имеет смысл. В общем, вы, вероятно, ожидаете, что m
будет Monad
. Однако учтите, что даже если m
составляет a Monad
, его состав с IO
может не быть (see this).
Value1 -> IO (Maybe Value2)
Value2 -> IO (Maybe Value3)
Value3 -> IO (Maybe Value4)
Ах, теперь вы говорите! Абстракция, которую вы ищете, это MaybeT
и состав Kleisli (>=>)
. Затем, например,
import Control.Monad ((>=>))
import Control.Monad.Trans.Maybe (MaybeT(..))
rest1 :: Value1 -> IO (Maybe Value2)
rest2 :: Value2 -> IO (Maybe Value3)
rest3 :: Value3 -> IO (Maybe Value4)
rest4 :: Value1 -> IO (Maybe Value4)
rest4 x = runMaybeT ((MaybeT . rest1 >=> MaybeT . rest2 >=> MaybeT . rest3) x)
Это все еще выглядит немного уродливым. Возможно, нужно реорганизовать ваши функции rest1
, rest2
и rest3
. Как было указано в комментариях, MaybeT IO a
может быть преобразован в IO (Maybe a)
(на самом деле это именно то, что runMaybeT
и MaybeT
do).
import Control.Monad ((>=>))
import Control.Monad.Trans.Maybe (MaybeT(..))
rest1 :: Value1 -> MaybeT IO Value2
rest2 :: Value2 -> MaybeT IO Value3
rest3 :: Value3 -> MaybeT IO Value4
rest4 :: Value1 -> MaybeT IO Value4
rest4 = rest1 >=> rest2 >=> rest3
Вы ищете состав Kliesli '(> =>)' Проверьте здесь Http: // hackage .haskell.org/package/base-4.9.1.0/docs/Control-Monad.html # v: -62--61--62- – zeronone
Дополнительно 'IO (возможно, a) ~ MaybeT IO a' и' MaybeT' является определенном в http://hackage.haskell.org/package/transformers-0.5.2.0/docs/Control-Monad-Trans-Maybe.html#v:MaybeT – zeronone