Haskell Language
Proxy
Ricerca…
Utilizzo del proxy
Il tipo Proxy :: k -> * , che si trova in Data.Proxy , viene utilizzato quando è necessario fornire al compilatore alcune informazioni sul tipo, ad esempio per selezionare un'istanza di classe di tipo, che tuttavia è irrilevante in fase di runtime.
{-# LANGUAGE PolyKinds #-}
data Proxy a = Proxy
Funzioni che utilizzano un Proxy genere utilizzano ScopedTypeVariables scegliere un'istanza del tipo classe basata sulla a tipo.
Ad esempio, il classico esempio di una funzione ambigua,
showread :: String -> String
showread = show . read
che si traduce in un errore di tipo perché l'elaboratore non sa quale istanza di Show o Read da usare, può essere risolto usando il Proxy :
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Proxy
showread :: forall a. (Show a, Read a) => Proxy a -> String -> String
showread _ = (show :: a -> String) . read
Quando si chiama una funzione con Proxy , è necessario utilizzare un tipo di annotazione per dichiarare che a volevi dire.
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 parse
L'idioma "proxy polimorfico"
Poiché il Proxy non contiene informazioni sul runtime, non è mai necessario associare il modello al costruttore del Proxy . Quindi un idioma comune è quello di astrarre il tipo di dati Proxy usando una variabile di tipo.
showread :: forall proxy a. (Show a, Read a) => proxy a -> String -> String
showread _ = (show :: a -> String) . read
Ora, se ti capita di avere un fa in scope per qualche f , non devi scrivere Proxy :: Proxy a quando chiami f .
ghci> let chars = "foo" -- chars :: [Char]
ghci> showread chars "'a'"
"'a'"
Proxy è come ()
Poiché Proxy non contiene informazioni di runtime, puoi sempre scrivere una trasformazione naturale fa -> Proxy a per qualsiasi f .
proxy :: f a -> Proxy a
proxy _ = Proxy
Questo è esattamente come qualsiasi valore dato può sempre essere cancellato a () :
unit :: a -> ()
unit _ = ()
Tecnicamente, Proxy è l'oggetto terminale nella categoria dei funtori, proprio come () è l'oggetto terminale nella categoria di valori.