Code does not compile without ScopedTypeVariables
Feel free to change the summary, I have no idea how to summarize this issue.
The code below fails to compile with Couldn't match type A with B
and The function X is applied to one argument, but its type Y has none
and some more (full output is attached below the code). However, simply enabling a language feature (ScopedTypeVariable
) makes the code compile. If this is not a bug in the compiler then the message should be improved, because nothing in it points to the solution.
I always thought of ScopedTypeVariables as allowing me to sprinkle :: T
throughout the code, in more places than GHC would normally allow. I did not expect that merely enabling this language feature without any other changes in the source code would have any effect on the output.
Dependencies: servant, servant-server
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
-- {-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Proxy
import Servant.API
import Servant.Server
data Credentials = Credential !String
instance (HasServer sublayout) => HasServer (Credentials :> sublayout) where
type ServerT (Credentials :> sublayout) m =
Credentials -> ServerT sublayout m
route Proxy subserver request respond = do
let mbSessionIdString = lookup "cookie" [("cookie", "session id")]
mbCredentials = fmap Credential mbSessionIdString
case mbCredentials of
Nothing -> error "No credentials supplied"
Just cred -> route (Proxy :: Proxy sublayout) (subserver cred) request respond
[1 of 1] Compiling Main ( Bug.hs, interpreted )
Bug.hs:30:60:
Couldn't match type ‘ServerT
sublayout
(either-4.4.1:Control.Monad.Trans.Either.EitherT ServantErr IO)’
with ‘ServerT
layout0
(either-4.4.1:Control.Monad.Trans.Either.EitherT ServantErr IO)’
NB: ‘ServerT’ is a type function, and may not be injective
The type variable ‘layout0’ is ambiguous
Expected type: Credentials -> Server layout0
Actual type: ServerT
(Credentials :> sublayout)
(either-4.4.1:Control.Monad.Trans.Either.EitherT ServantErr IO)
Relevant bindings include
subserver :: Server (Credentials :> sublayout)
(bound at Bug.hs:24:17)
route :: Proxy (Credentials :> sublayout)
-> Server (Credentials :> sublayout)
-> Servant.Server.Internal.RoutingApplication
(bound at Bug.hs:24:5)
The function ‘subserver’ is applied to one argument,
but its type ‘Server (Credentials :> sublayout)’ has none
In the second argument of ‘route’, namely ‘(subserver cred)’
In the expression:
route (Proxy :: Proxy sublayout) (subserver cred) request respond
Failed, modules loaded: none.
Trac metadata
Trac field | Value |
---|---|
Version | 7.10.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |