我正在使用Haskell的Polysemy库,并且在尝试打印到StdOut时遇到了巨大的头痛。这是我的代码:
apiServer :: (Member Trace r, Member (Embed IO) r) => ServerT Api (Sem r)
apiServer = test :<|> values
where
test :: Sem r String
test = do
return "Server up!"
values :: Member Trace r => Sem r Value
values =
do
_ <- trace (show dummyValues)
return dummyValues
api :: Proxy Api
api = Proxy
serverHandler :: Handler [Char] :<|> Handler Value
serverHandler = hoistServer api interpretServer apiServer
where
interpretServer :: Sem '[Trace, Embed IO] a -> Handler a
interpretServer sem =
sem
|> traceToStdout
|> runM
错误为
• Couldn't match expected type: Handler a
with actual type: IO a
• In the expression: sem |> traceToStdout |> runM
In an equation for ‘interpretServer’:
interpretServer sem = sem |> traceToStdout |> runM
In an equation for ‘serverHandler’:
serverHandler
= hoistServer api interpretServer apiServer
where
interpretServer :: Sem '[Trace, Embed IO] a -> Handler a
interpretServer sem = sem |> traceToStdout |> runM
• Relevant bindings include
sem :: Sem '[Trace, Embed IO] a (bound at src/Lib.hs:58:21)
interpretServer :: Sem '[Trace, Embed IO] a -> Handler a
(bound at src/Lib.hs:58:5)
我知道我应该以某种方式解释Embed
,但我不知道如何解释。我尝试了runEmbedded
,但不知道在第一个arg中放什么。
我设法解决了这个问题,因为我知道先运行traceToStdout
,然后运行runM
会给我一个IO
,而忽略它会给我带来Handler
。
我可以通过在末尾添加liftIO
来修复它,将IO
Monad提升到Handler
Monad:中
serverHandler = hoistServer api interpretServer apiServer
where
interpretServer :: Sem '[Trace, Embed IO] a -> Handler a
interpretServer sem =
sem
|> traceToStdout
|> runM
|> liftIO