Ich möchte eine Art sichere Lookup-Funktion für die folgenden Datentypen entwickeln:Typ sichere Lookup auf heterogene Listen in Haskell
lookupAttr :: (KnownSymbol s, Lookup s env ~ 'Just t) => Proxy s -> Attr env -> t
lookupAttr s ((s',t) :* env')
= case sameSymbol s s' of
Just Refl -> t
Nothing -> lookupAttr s env'
wo Lookup
:
data Attr (xs :: [(Symbol,*)]) where
Nil :: Attr '[]
(:*) :: KnownSymbol s => (Proxy s, t) -> Attr xs -> Attr ('(s , t) ': xs)
Die offensichtliche Lookup-Funktion sein würde, Typ Familie ist in Singletons-Bibliothek definiert. Diese Definition versagt Überprüfung GHC 7.10.3 mit der folgenden Fehlermeldung eingeben:
Could not deduce (Lookup s xs ~ 'Just t)
from the context (KnownSymbol s, Lookup s env ~ 'Just t)
bound by the type signature for
lookupAttr :: (KnownSymbol s, Lookup s env ~ 'Just t) =>
Proxy s -> Attr env -> t
Diese Nachricht ist für den rekursiven Aufruf lookupAttr s env'
erzeugt wird. Dies ist sinnvoll, da wir, dass, wenn
Lookup s ('(s',t') ': env) ~ 'Just t
hält, und
s :~: s'
ist nicht beweisbar, dann
Lookup s env ~ 'Just t
muss halten. Meine Frage ist, wie kann ich Haskell Typ Checker überzeugen, dass dies tatsächlich wahr ist?
Wo ist 'sameSymbol' definiert? Geht das auch von der Singletons-Bibliothek? – Kwarrtz
Oh, vergiss es. Gefunden in [GHC.TypeLits] (https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-TypeLits.html). – Kwarrtz
Wenn Sie Strings zur Darstellung gebundener Variablen verwenden, zahlen Sie einen erheblichen Preis für die Komplexität Ihrer Sprachimplementierung. Capture-Vermeidung Substitution und Alpha-Äquivalenz sind beide notorisch schwierig, um richtig zu machen, ganz zu schweigen von den Kosten des Kampfes mit 'Symbol's ziemlich jacky Umsetzung in GHC. Wenn Sie ein typsicheres embedded DSL bauen, sollten Sie [HOAS] (https://en.wikipedia.org/wiki/Higher-order_abstract_syntax) ernsthaft als eine einfachere Alternative betrachten. –