Proxies
Using Proxy
Section titled “Using Proxy”The Proxy :: k -> * type, found in Data.Proxy, is used when you need to give the compiler some type information - eg, to pick a type class instance - which is nonetheless irrelevant at runtime.
{-# LANGUAGE PolyKinds #-}
data Proxy a = ProxyFunctions which use a Proxy typically use ScopedTypeVariables to pick a type class instance based on the a type.
For example, the classic example of an ambiguous function,
showread :: String -> Stringshowread = show . readwhich results in a type error because the elaborator doesn’t know which instance of Show or Read to use, can be resolved using Proxy:
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Proxy
showread :: forall a. (Show a, Read a) => Proxy a -> String -> Stringshowread _ = (show :: a -> String) . readWhen calling a function with Proxy, you need to use a type annotation to declare which a you meant.
ghci> showread (Proxy :: Proxy Int) "3""3"ghci> showread (Proxy :: Proxy Bool) "'m'" -- attempt to parse a char literal as a Bool"*** Exception: Prelude.read: no parseThe “polymorphic proxy” idiom
Section titled “The “polymorphic proxy” idiom”Since Proxy contains no runtime information, there is never a need to pattern-match on the Proxy constructor. So a common idiom is to abstract over the Proxy datatype using a type variable.
showread :: forall proxy a. (Show a, Read a) => proxy a -> String -> Stringshowread _ = (show :: a -> String) . readNow, if you happen to have an f a in scope for some f, you don’t need to write out Proxy :: Proxy a when calling f.
ghci> let chars = "foo" -- chars :: [Char]ghci> showread chars "'a'""'a'"Proxy is like ()
Section titled “Proxy is like ()”Since Proxy contains no runtime information, you can always write a natural transformation f a -> Proxy a for any f.
proxy :: f a -> Proxy aproxy _ = ProxyThis is just like how any given value can always be erased to ():
unit :: a -> ()unit _ = ()Technically, Proxy is the terminal object in the category of functors, just like () is the terminal object in the category of values.