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.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow