Search code examples
haskellservant

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


I'm stuck with the following error, after a major code refactor:

    • 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)      

I've read, and re-read the documentation, but cannot seem to find where the error is. This code was working earlier, and I've changed Endpoint.AuditLog.server :: Routes (AsServerT AppM) to Endpoint.AuditLog.server :: AppRunners m n -> Routes (AsServerT n) and confirmed that the type of the following expressions seems to be similar across the refactor; basically Routes (AsServerT AppM) has changed to Routes (AsServerT (AppM '[] ()))

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

The following snippet is also structurally the same across the refactor:

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

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

How do I go about debugging this error? Since there are a lot of type-families involved, is there any way to see what the following type-level expressions simplify to:

  • ServerT Routes (AppM '[] ())
  • Endpoint.AuditLog.Routes (AsServerT (AppM '[] ()))

Solution

  • Expletive! Expletive! Expletive!

    I was missing a toServant -

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