作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
一个 servant-server Handler是 ExceptT
上的新类型包装器,并且有 MonadThrow
的实例, MonadCatch
, MonadError
, ETC。
这可能是一个有点做作的例子,但它显示了我经常面临的一个问题:
在处理程序中,我想调用三个返回 Either String Int
的函数,然后执行 Int -> Int -> Int -> IO (Either SomeError Text)
类型的计算,取三个Int
s 从以前开始。
我应该如何构建此代码以确保尽早返回错误?
我看到我可以使用 Either
的Monad
实例“折叠”前三个 Either String Int
计算成例如Either String (Int,Int,Int)
,然后绑定(bind)IO
计算到某个结果值,然后使用 case
决定是返回成功的结果还是使用throwError
扔SomeError
类型(转换后?),但我希望能够如下所示:
f, g, h :: Either String Int
a :: Int -> Int -> Int -> IO (Either SomeError Text)
myHandler :: Handler Text
myHandler = do
x1 <- f
x2 <- g
x3 <- h
liftIO $ convertError $ (a x1 x2 x3)
最佳答案
假设你有一个函数 strToServantErr :: String -> ServantErr
用于转换 f,g,h
返回的错误进入可以由您的处理程序返回的错误,然后我们可以使用:
liftEither
获取 Either String Int
转入 ExceptT String
s。 withExceptT
从 ExceptT String
转换至ExceptT ServantErr
根据 Handler
的要求. x1 <- withExceptT strToServantErr $ liftEither f
mapM
使它更整洁:
[x1, x2, x3] <- mapM (withExceptT strToServantErr . liftEither) [f, g, h]
convertError
函数到
someErrorToServantErr
为了统一并假设它的类型为
SomeError -> ServantErr
,那么我们可以这样做:
result <- liftIO $ a x1 x2 x3
withExceptT someErrorToServantErr $ liftEither result
IO
a
的计算,然后将其提升到
ExceptT
并转换异常类型。
myHandler :: Handler Text
myHandler = do
[x1, x2, x3] <- mapM (liftMapE strToServantErr) [f, g, h]
eitherResult <- liftIO $ a x1 x2 x3
liftMapE someErrorToServantErr eitherResult
where liftMapE f = withExceptT f . liftEither
myHandler :: Handler Text
myHandler = do
let [x1, x2, x3] = map (liftMapE strToServantErr) [f, g, h] -- [Handler Int]
tmp <- a <$> x1 <*> x2 <*> x3 -- IO (Either SomeError Text)
eitherResult <- liftIO $ tmp
liftMapE someErrorToServantErr eitherResult
where liftMapE f = withExceptT f . liftEither
关于haskell - 仆人处理程序中的任一计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49527770/
用Servant实现文件上传API的方法是什么?我正在尝试处理“标准”multipart/form-data 但不知道如何在 Servant 中声明它。 这显然行不通,因为它无法处理多部分: type
我是一名优秀的程序员,十分优秀!