In Haskell ist ein Proxy ein Typ-Zeuge-Wert, der es erleichtert, bestimmte Typen zu übergeben
data Proxy a = Proxy
Ein Beispiel dafür findet sich hier in json-schema:
class JSONSchema a where
schema :: Proxy a -> Schema
so könntest du schema (Proxy :: Proxy (Int,Char))
verwenden, um herauszufinden, wie die JSON-Repräsentation für ein Int-Char-Tupel aussehen würde (wahrscheinlich ein Array).
Warum verwenden Leute Proxies? Es scheint mir, dass dasselbe mit
class JSONSchema a where
schema :: Schema a
erreicht werden könnte, ähnlich wie beim Bounded
-Typklasse funktioniert. Ich dachte zuerst, es könnte einfacher sein, das Schema eines bestimmten Werts zu erhalten, wenn man Proxies verwendet, aber das scheint nicht wahr zu sein:
{-# LANGUAGE ScopedTypeVariables #-}
schemaOf :: JSONSchema a => a -> Schema a
schemaOf (v :: x) = schema (Proxy :: Proxy x) -- Mit proxy
schemaOf (v :: x) = schema :: Schema x -- Mit `:: a`
schemaOf _ = schema -- Noch einfacher mit `:: a`
Außerdem könnte man sich Sorgen machen, ob die Proxy
-Werte tatsächlich zur Laufzeit beseitigt werden, was ein Optimierungsproblem darstellt, das nicht vorhanden ist, wenn man den :: a
-Ansatz verwendet.
Wenn der :: a
-Ansatz, wie von Bounded
angewendet, das gleiche Ergebnis mit kürzerem Code und weniger Sorgen um Optimierung erzielt, warum verwenden Leute dann Proxies? Was sind die Vorteile von Proxies?
EDIT: Einige Antworten und Kommentatoren wiesen zu Recht darauf hin, dass der :: a
-Ansatz den data Schema = ...
-Typ mit einem "nutzlosen" Typenparameter befleckt - zumindest aus der Sicht der reinen Datenstruktur selbst, die den a
nie verwendet (siehe hier).
Der Vorschlag besteht darin, stattdessen den Phantomtyp Tagged s b
zu verwenden, der es ermöglicht, die beiden Aspekte voneinander zu trennen (Tagged a Schema
kombiniert den nicht-parametrischen Schema-Typ mit einer Typvariable a
), was streng besser ist als der :: a
-Ansatz.
Also sollte meine Frage besser lauten Was sind die Vorteile von Proxies gegenüber dem tagged-Ansatz?