Proxy is a small Haskell type from Data.Proxy that carries type information without carrying a corresponding runtime value. Its single constructor has no fields, so its type variable is phantom: the type system knows it, while the runtime value does not. section 17.1.2
Passing a type without a value
A function can receive Proxy a and use the type a to choose behavior while ignoring the Proxy value itself. For example, readProxy :: Read a => Proxy a -> String -> a parses according to its proxy type: readProxy intProxy has result type String -> Int, while readProxy stringProxy has result type String -> String. section 17.1.2
Use Proxy when an API needs type-level information but no ordinary value:
- Define a proxy by giving it a concrete type, such as Proxy Int or Proxy String, and constructing it with Proxy. section 17.1.2
- Represent a Servant API as a type, then provide a value such as todoApi :: Proxy TodoApi for functions that require the API type. section 17.1.1 section 17.1.2
- Remember that the proxy itself contains no endpoint data or other runtime fields; its purpose is to carry the chosen type to the type system. section 17.1.2
data Proxy a = Proxy
Inspect the minimal definition: data Proxy a = Proxy. section 17.1.2
Listing 17.2 A module to define the type for our Servant API together with a Proxy value
{-# LANGUAGE DataKinds #-} #1
{-# LANGUAGE TypeOperators #-} #1
module Todos.Api
( TodoApi,
todoApi,
)
where
import Data.Proxy (Proxy (..)) #2
import Servant.API #2
import Todos.Types (TodoEntry) #2
type TodoApi = #3
"entries" :> Get '[JSON] [TodoEntry] #3
:<|> "add" :> ReqBody '[JSON] TodoEntry :> #3
PostCreated '[JSON] Int #3
:<|> "toggle" :> Capture "id" Int :> #3
PatchNoContent #3
todoApi :: Proxy TodoApi #4
todoApi = Proxy #4
See a complete Servant API module pairing a type alias with todoApi :: Proxy TodoApi. section 17.1.2
