Haskell Language
Proxy
Szukaj…
Korzystanie z serwera proxy
Typ Proxy :: k -> * , znajdujący się w Data.Proxy , jest używany, gdy trzeba podać kompilatorowi jakieś informacje o typie - np. Data.Proxy instancję klasy typu - co jednak nie ma znaczenia w czasie wykonywania.
{-# LANGUAGE PolyKinds #-}
data Proxy a = Proxy
Funkcje, które używają Proxy zazwyczaj korzystają ScopedTypeVariables wybrać instancję klasy w oparciu o typ a typem.
Na przykład klasyczny przykład niejednoznacznej funkcji,
showread :: String -> String
showread = show . read
co powoduje błąd typu, ponieważ twórca nie wie, która instancja Show lub Read do użycia, można rozwiązać za pomocą Proxy :
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Proxy
showread :: forall a. (Show a, Read a) => Proxy a -> String -> String
showread _ = (show :: a -> String) . read
Przy wywołaniu funkcji z Proxy , trzeba użyć typu adnotacji zadeklarować które chodziło. a
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
Idiom „polimorficzne proxy”
Ponieważ Proxy nie zawiera informacji o środowisku wykonawczym, nigdy nie ma potrzeby dopasowywania wzorców w konstruktorze Proxy . Dlatego powszechnym idiomem jest abstrakty na typie danych Proxy za pomocą zmiennej typu.
showread :: forall proxy a. (Show a, Read a) => proxy a -> String -> String
showread _ = (show :: a -> String) . read
Teraz, jeśli akurat masz fa w zakresie dla jakiegoś f , nie musisz wypisywać Proxy :: Proxy a podczas wywoływania f .
ghci> let chars = "foo" -- chars :: [Char]
ghci> showread chars "'a'"
"'a'"
Proxy jest jak ()
Ponieważ Proxy nie zawiera informacji o środowisku wykonawczym, zawsze możesz napisać naturalną transformację fa -> Proxy a dla dowolnego f .
proxy :: f a -> Proxy a
proxy _ = Proxy
Jest to tak, jak zawsze można usunąć dowolną wartość do () :
unit :: a -> ()
unit _ = ()
Technicznie rzecz biorąc, Proxy jest obiektem końcowym w kategorii funktorów, podobnie jak () jest obiektem końcowym w kategorii wartości.