一个关于仆人休息api的简单例子,或者"如何恰当地混合monad"?

时间:2016-03-25 10:41:02

标签: 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  

我无法编译,因为很多错误&#34;无法匹配预期类型&#34;在不同的地方。我猜是因为我在&#34; getItems&#34;中混合了2个不同的monad。但不仅如此。

1 个答案:

答案 0 :(得分:4)

下面:

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

ExceptT ServantErr IO [MyData]IO (Either ServantErr [MyData]ExceptT的作用是什么。它消除了IO a newtype。但你想走另一条路!

您可以使用runExceptT将任何ExceptT ServantErr IO a操作解除为ExceptT操作。它基本上告诉IO包装器&#34;只需将IO操作的结果放在成功上下文&#34;。

由于你的整个do-block似乎都存在getItems :: ExceptT ServantErr IO [MyData] getItems = liftIO $ do aa <- nextRandom -- IO bb <- getCurrentTime -- IO cc <- getDataFromDb -- IO ... ,你可以写:

IO

而不是单独解除每个Either行动。

其他常见情况:

所有这些功能都非常简单,查看它们的源代码是有益的。

相关问题