通过一些糟糕的编程,我再次陷入了类型的糟糕境地。
有没有办法将Either a (IO b)
转换为IO (Either a b)
?我知道,让自己陷入这种情况并不是很好的编程,因此我也愿意接受有关如何避免此类情况的建议。
最佳答案
当然!
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
,因此它会为我们处理模式匹配,确定我们是否有根据您的情况,为a
或IO b
。- 如果我们有一个
a
,我们只需将其转换为IO(要么 a b)
。构造函数Left::a -> Either a b
完成第一部分,而IO
是一个 monad,因此我们可以使用return
来执行要么 a b -> IO(要么 a b)
。 如果我们有一个
IO b
,我们需要将其转换为IO(要么 a b)
。我们可以使用 do 表示法来做到这一点:given iob = do b <- iob return . Right $ b
使用
返回。右
为b -> IO(要么a b)
。但这正是 Monads 中mapM::Monad m => (a -> b) -> m a -> m b
的情况:given iob = mapM Right iob
。不过,大多数人不使用mapM
,因为它只是fmap
对 Monad 的专门化,所以我们将使用fmap
:given iob = fmap Right iob
,或者,pointfree :given = fmap Right
。
关于haskell - 将 Either a (IO b) 转换为 IO (Ei a b),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26090827/