voglio sviluppare una funzione di tipo di ricerca sicuro per i seguenti tipi di dati:Tipo di ricerca sicura su liste eterogenee in Haskell
data Attr (xs :: [(Symbol,*)]) where
Nil :: Attr '[]
(:*) :: KnownSymbol s => (Proxy s, t) -> Attr xs -> Attr ('(s , t) ': xs)
La funzione di ricerca ovvia sarebbe come:
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'
dove Lookup
la famiglia di tipi è definita nella libreria di singleton. Questa definizione non riesce a digitare controllo sulla GHC 7.10.3 con il seguente messaggio di errore:
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
Questo messaggio viene generato per la chiamata ricorsiva lookupAttr s env'
. Questo è ragionevole, dal momento che abbiamo che se
Lookup s ('(s',t') ': env) ~ 'Just t
stive, e
s :~: s'
non è dimostrabile, allora
Lookup s env ~ 'Just t
deve tenere. La mia domanda è, come posso convincere il correttore di tipo Haskell che questo è vero?
Dove è definito 'sameSymbol'? È anche dalla biblioteca dei singleton? – Kwarrtz
Oh, non importa. Trovato in [GHC.TypeLits] (https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-TypeLits.html). – Kwarrtz
Quando si usano le stringhe per rappresentare variabili vincolate, si paga un prezzo significativo nella complessità dell'implementazione linguistica. La sostituzione e l'alfa-equivalenza che evitano le catture sono notoriamente difficili da ottenere, per non parlare del costo della battaglia con l'implementazione piuttosto janky di "Symbol" in GHC. Se stai creando un DSL incorporato sicuro per i caratteri, penso che dovresti prendere in seria considerazione [HOAS] (https://en.wikipedia.org/wiki/Higher-order_abstract_syntax) come alternativa più semplice. –