You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell Polysemy库输出到StdOut遇类型错误,求解决方案

解决Polysemy与Servant Handler的类型不匹配问题

你的报错核心是类型不匹配:runM将Polysemy的Sem计算转换为了IO a,但interpretServer要求返回Servant的Handler a类型。解决方法很简单,只需要把IO动作嵌入到Handler上下文即可。

修改后的代码

import Servant.Server (Handler, liftIO)

apiServer :: (Member Trace r, Member (Embed IO) r) => ServerT Api (Sem r)
apiServer = test :<|> values
  where
    test :: Sem r String
    test = return "Server up!"

    values :: Member Trace r => Sem r Value
    values = do
      _ <- trace (show dummyValues)
      return dummyValues

api :: Proxy Api
api = Proxy

serverHandler :: Handler String :<|> Handler Value
serverHandler = hoistServer api interpretServer apiServer
  where
    interpretServer :: Sem '[Trace, Embed IO] a -> Handler a
    interpretServer sem =
      sem
        |> traceToStdout
        |> runM
        |> liftIO  -- 将IO结果转换为Handler类型

关键说明

  • traceToStdout:将Trace效应解释为向标准输出打印日志
  • runM:处理Embed IO效应,把Sem计算直接转换为原生IO动作
  • liftIO:Servant Handler monad提供的函数,用于将任意IO动作提升到Handler上下文,补全类型匹配

关于你提到的runEmbedded:这个函数是用来解释自定义的Embed m效应(比如嵌入非IO的monad),但你的场景中Embed的就是IO,所以runM已经足够处理,不需要使用runEmbedded。

内容的提问来源于stack exchange,提问作者Nimrod Sadeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:45:54