转换a(IO b)到IO(a b)

时间:2014-09-28 23:58:59

标签: haskell types io

再一次,通过一些糟糕的,糟糕的编程,我已经设法让自己陷入了类型的可怕境地。

有没有办法将Either a (IO b)转换为IO (Either a b)?我知道,让自己陷入这种状况并不是很好的编程,所以我也愿意接受如何避免这种情况的建议。

1 个答案:

答案 0 :(得分:5)

当然!

convert :: Either a (IO b) -> IO (Either a b)
convert = either (return . Left) (fmap Right)

现在,如果你想将IO (Either a b)转换为Either a (IO b),你就会遇到麻烦,但是你没有,所以你没事。

让我们看看convert是如何运作的:

  • either :: (a -> c) -> (b -> c) -> Either a b -> c,因此它会为我们处理模式匹配,确定我们是否有aIO b
  • 如果我们有a,我们只需要将其转换为IO (Either a b)。构造函数Left :: a -> Either a b执行第一部分,IO是monad,因此我们可以使用return执行Either a b -> IO (Either a b)
  • 如果我们有IO b,我们需要将其转换为IO (Either a b)。我们可以用符号来做到这一点:

    given iob = do
      b <- iob
      return . Right $ b
    

    使用return . Right作为b -> IO (Either a b)。但这正是Monads中mapM :: Monad m => (a -> b) -> m a -> m b的情况:given iob = mapM Right iob。但是,大多数人都不会使用mapM,因为它只是fmap对Monads的专长,所以我们会使用fmap:{{1 },或者,pointfree:given iob = fmap Right iob