如何为 Servant 的类型错误建立直觉?

How to build an intuition for Servant's type-errors?

在主要代码重构之后,我遇到了以下错误:

    • Couldn't match type ‘Endpoint.AuditLog.Routes
                             (AsServerT (AppM '[] ()))’
      with

      --
      -- complete API type comes here
      --

      Expected type: ServerT Routes (AppM '[] ())
        Actual type: Endpoint.AuditLog.Routes (AsServerT (AppM '[] ()))
    • In the expression: (Endpoint.AuditLog.server appRunners)
      In an equation for ‘prodServer’:
          prodServer = (Endpoint.AuditLog.server appRunners)      

我已经阅读并重新阅读 the documentation,但似乎无法找到错误所在。这段代码之前可以正常工作,我已将 Endpoint.AuditLog.server :: Routes (AsServerT AppM) 更改为 Endpoint.AuditLog.server :: AppRunners m n -> Routes (AsServerT n) 并确认以下表达式的类型在整个重构过程中似乎相似;基本上 Routes (AsServerT AppM) 变成了 Routes (AsServerT (AppM '[] ()))

ghci> :t (Endpoint.AuditLog.server AppM.appRunners)
(Endpoint.AuditLog.server AppM.appRunners) :: Routes (AsServerT (AppM '[] ()))

以下代码段在整个重构过程中在结构上也是相同的:

type Routes = (ToServant Endpoint.AuditLog.Routes AsApi)

prodServer :: ServerT Routes (AppM '[] ())
prodServer = (Endpoint.AuditLog.server AppM.appRunners)

我该如何调试这个错误?由于涉及到很多类型族,有什么办法可以看出以下类型级表达式简化为:

咒骂!咒骂!咒骂!

我少了一个 toServant -

prodServer :: ServerT Routes (AppM '[] ())
prodServer = (toServant $ Endpoint.AuditLog.server AppM.appRunners)