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.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow