rest - 一个servant或 "how to mix monads properly"中rest api的简单示例?

标签 rest haskell monads servant

我想在servant 0.5中构建一个rest api的简单示例:

data MyData = MyData { var1 :: Int, var2 :: String } 

app :: Application
app = serve api server

api :: Proxy API
api = Proxy

server :: Server API
server = getItems

getItems :: EitherT ServantErr IO [MyData]
getItems = runEitherT $ do
    aa <- nextRandom -- IO
    bb <- getCurrentTime -- IO
    cc <- getDataFromDb -- IO

    --noteT ??? How??? 
    --MaybeT ??? How??? 

    return $ Just [MyData 111 222] 


startApp :: IO ()
startApp = run 8080 app  

由于不同地方有很多“无法匹配预期类型”的错误,我无法编译它。我想这是因为我在“getItems”中混合了两个不同的单子(monad)。但不仅如此。

最佳答案

这里:

getItems :: ExceptT ServantErr IO [MyData]
getItems = runExceptT $ do

什么runExceptT确实是从 ExceptT ServantErr IO [MyData]IO (Either ServantErr [MyData])。它消除了 ExceptT 新类型。但是你想要走另一条路!

您可以使用liftIO将任何 IO a 操作提升为 ExceptT ServantErr IO a 操作。它基本上告诉 ExceptT 包装器“将 IO 操作的结果放入成功上下文中”。

由于您的整个 do-block 似乎都位于 IO 中,因此您可以编写:

getItems :: ExceptT ServantErr IO [MyData]
getItems = liftIO $ do
    aa <- nextRandom -- IO
    bb <- getCurrentTime -- IO
    cc <- getDataFromDb -- IO
    ...

而不是单独提升每个 IO 操作。

其他常见情况:

所有这些函数都非常简单,查看它们的源代码很有启发性。

关于rest - 一个servant或 "how to mix monads properly"中rest api的简单示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36218369/

相关文章:

haskell - 正确标记 AST

c# - 在 react 性管道中管理状态

c# - 将 LINQ 查询语法与自定义 Maybe monad 实现结合使用

parsing - 解析时添加运算符

haskell - 在参数类型而不是函数类型中设置约束有什么作用?

正则表达式匹配特定的 URI

java - 如何创建一个虚拟 REST 服务器 API 来检查我的 android http 请求\响应?

haskell - FP 中模式匹配相对于条件的优势是什么(通俗地说)?

web-services - REST 搜索接口(interface)和 GET 的幂等性

java - 在 Grails/Java 上使用 Yahoo Fire Eagle