Haskell Language
volmachten
Zoeken…
Proxy gebruiken
Het type Proxy :: k -> *
, te vinden in Data.Proxy
, wordt gebruikt wanneer u de compiler wat type-informatie moet geven, bijvoorbeeld om een instantie van een type klasse te kiezen, die niettemin tijdens runtime niet relevant is.
{-# LANGUAGE PolyKinds #-}
data Proxy a = Proxy
Functies die gebruik maken van een Proxy
gebruiken meestal ScopedTypeVariables
naar een soort klasse-instantie op basis van de pick- a
type.
Het klassieke voorbeeld van een ambigue functie,
showread :: String -> String
showread = show . read
wat resulteert in een typefout omdat de ontwikkelaar niet weet welke instantie van Show
of Read
moet worden gebruikt, kan worden opgelost met behulp van Proxy
:
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Proxy
showread :: forall a. (Show a, Read a) => Proxy a -> String -> String
showread _ = (show :: a -> String) . read
Bij het aanroepen van een functie met een Proxy
, moet je een soort annotatie gebruiken om te verklaren die a
je bedoeld.
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
Het idioom "polymorfe proxy"
Aangezien Proxy
geen runtime-informatie bevat, is er nooit een noodzaak om patronen te matchen op de Proxy
constructor. Een veel voorkomend idioom is dus om het Proxy
gegevenstype samen te vatten met behulp van een typevariabele.
showread :: forall proxy a. (Show a, Read a) => proxy a -> String -> String
showread _ = (show :: a -> String) . read
Als u nu een fa
voor sommige f
, hoeft u Proxy :: Proxy a
niet te schrijven als u f
belt.
ghci> let chars = "foo" -- chars :: [Char]
ghci> showread chars "'a'"
"'a'"
Proxy is als ()
Aangezien Proxy
geen runtime-informatie bevat, kunt u altijd een natuurlijke transformatie schrijven fa -> Proxy a
voor elke f
.
proxy :: f a -> Proxy a
proxy _ = Proxy
Dit is net zoals hoe een bepaalde waarde altijd kan worden gewist naar ()
:
unit :: a -> ()
unit _ = ()
Technisch gezien is Proxy
het eindobject in de categorie functors, net zoals ()
het eindobject in de categorie waarden.