Data.Proxy in the public servant API (why does Proxy not work with ScopedTypeVariables)

I'm excited about servant , and I'm fine with its internal text-level magic until it gets in the way, and the only thing that bothers me is the use of proxy type in a public API. Here is the code :

serve :: HasServer layout => Proxy layout -> Server layout -> Application serve p server = toApplication (runRouter (route p (return (RR (Right server))))) 

As I understand it, proxy types are pretty simple things and are necessary for type transfer when you have no value with this type. So, why transfer a proxy medium that supports a layout type when there is already a layout type in the server type parameter? I tried cloning the repo service and changing the code:

 {-# LANGUAGE ScopedTypeVariables #-} serve :: forall layout . HasServer layout => Server layout -> Application serve server = toApplication (runRouter (route p (return (RR (Right server))))) where p :: Proxy layout p = Proxy 

And unexpectedly for me, this will not compile (telling something about the mismatch of the layout type). But why, shouldn't my local p have the same layout type as the server (with ScopedTypeVariables enabled)?

+6
source share
2 answers

Family types are not injective, but Server is one. Therefore, if you pass Server MyAPI this function, the GHC will not be able to conclude layout = MyAPI . Unfortunately, we really need a Proxy . Even if we had injection types of families, this did not help:

 type API1 = Get '[JSON] User type API2 = Post '[JSON] User 

These two APIs are such as Server API1 = Server API2 , but API1 /= API2 , which actually shows us that Server should not be injective. The easiest way to eliminate the type of API we want to target is Proxy . On the other hand, this is often the only thing our APIs ask for in various servant packages.

+7
source

Server not a type constructor; it is a synonym for the type of the associated ServerT type in the HasServer class. Therefore, the layout found in Server layout does not eliminate the ambiguity of the HasServer constraint. We can only allow the Server layout type if we already have an instance of HasServer layout .

+1
source

All Articles