`(a -> m (Either eb)) -> Either ea -> m (Either eb)` 的一元函数?

Gus*_*ust 3 monads haskell either

有没有办法以更“单子”的方式编写这个函数,而不是诉诸于模式匹配Either

{-# LANGUAGE LambdaCase #-}

calculate :: (Monad m) => (a -> m (Either e b)) -> Either e a -> m (Either e b)
calculate f = \case
  Left err   -> return $ Left err
  Right vals -> f vals
Run Code Online (Sandbox Code Playgroud)

具体来说,对于我的用例来说,mIOf是一个函数,它接受输入并产生一些IO效果或失败的函数,而输入可能已经失败了。

也许使用ExceptT

luq*_*qui 5

是的,对我来说看起来很像ExceptT。尽管我可能不会使用具有此签名的函数 - 相反,我会ExceptT更广泛地使用,然后这个函数只是(=<<). 当然,这是基于用例的猜测。

但如果你必须:

calculate :: (Monad m) => (a -> m (Either e b)) -> Either e a -> m (Either e b)
calculate f m = runExceptT (ExceptT . f =<< ExceptT m)
Run Code Online (Sandbox Code Playgroud)