首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从IO转换为EitherT IO a

从IO转换为EitherT IO a
EN

Stack Overflow用户
提问于 2015-04-15 16:34:23
回答 3查看 989关注 0票数 1

我正在使用API的奴仆库。它运行在:EitherT (Int, String) IO a monad中。我有一个带有IO Maybe a类型的函数,并且希望使用它。

下面是一个有用的例子:

代码语言:javascript
复制
sourcesGetAll :: EitherT (Int, String) IO [Source]
sourcesGetAll = liftIO $ sourcesList h

sourcesList :: IO [Source]

但是现在我想把这两个函数结合起来

代码语言:javascript
复制
sourcesFind :: IO (Maybe Source)
sourcesGetOne :: EitherT (Int, String) IO Source
sourcesGetOne = ???

我想这样做:

代码语言:javascript
复制
maybeNotFound :: Maybe a -> Either (Int, String) a
maybeNotFound Nothing = Left (404, "Not Found")
maybeNotFound Just a  = Right a

我怎么处理那些花哨的单簧管呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-15 17:03:06

您可以使用hoistEither :: Monad m => Either a b -> EitherT a m b来实现这一点:

代码语言:javascript
复制
maybeNotFoundT :: IO (Maybe a) -> EitherT (Int, String) IO a
maybeNotFoundT maAct = do
  ma <- liftIO maAct -- get the Maybe a. Now ma :: Maybe a
  hoistEither $ maybeNotFound ma
票数 4
EN

Stack Overflow用户

发布于 2015-04-15 17:03:15

您可以将其分解为两个独立的问题:

  • IO (Maybe a)转换为MaybeT IO a
  • MaybeT IO a转换为EitherT (Int, String) a

第一个问题通过使用MaybeT构造函数解决:

代码语言:javascript
复制
MaybeT :: IO (Maybe a) -> MaybeT IO a

第二个问题通过使用来自noteT库的errors来解决:

代码语言:javascript
复制
noteT :: Monad m => a -> MaybeT m b -> EitherT a m b
票数 4
EN

Stack Overflow用户

发布于 2015-04-15 17:18:28

另一个答案是,由于在freenode上争吵不休:

代码语言:javascript
复制
sourcesGetOne = EitherT $ maybeNotFound <$> sourcesFind

所以问题是如何写一个函数。IO (Maybe a) -> EitherT (Int, String) IO a给出了一个函数f :: Maybe a -> Either (Int, String) a,那么一种方法是..。 myFunc action = EitherT (f <$> action) 如果你看一下EitherT的文档-- https://hackage.haskell.org/package/either-4.3.3.2/docs/Control-Monad-Trans-Either.html。然后你会看到EitherT (Int, String) IO a,实际上只是一个包装好的IO (Either (Int, String) a)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29655874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档