8

Esiste una connessione implementata tra l'uguaglianza propositional e promoted?Esiste una connessione tra `a: ~: b` e` (a: == b): ~: True`?

Diciamo che ho

prf :: x :~: y 

portata per alcuni Symbol s; dal pattern matching su di esso essendo Refl, posso trasformarla in

prf' :: (x :== y) :~: True 

come questo:

fromProp :: (KnownSymbol x, KnownSymbol y) => x :~: y -> (x :== y) :~: True 
fromProp Refl = Refl 

Ma per quanto riguarda l'altra direzione? Se provo

toProp :: (KnownSymbol x, KnownSymbol y) => (x :== y) :~: True -> x :~: y 
toProp Refl = Refl 

allora tutto quello che ottiene è

• Could not deduce: x ~ y 
    from the context: 'True ~ (x :== y) 
+1

Certo, 'toProp _ = unsafeCoerce Refl'. 'sameSymbol' è definito in questo modo, quindi dubito che tu possa fare di meglio. – user3237465

+1

Si potrebbe anche scrivere 'toProp Refl = fromJust $ sameSymbol (Proxy :: Proxy x) (Proxy :: Proxy y)' ma questo è solo leggermente migliore dell'uso di 'unsafeCoerce'. – user2407038

risposta

8

Sì, in corso tra le due rappresentazioni è possibile (assumendo la realizzazione di :== è corretto), ma richiede il calcolo.

Le informazioni necessarie non sono presenti nello stesso booleano (it's been erased to a single bit); devi recuperarlo. Ciò comporta l'interrogazione dei due partecipanti al test di uguaglianza booleana originale (il che significa che devi tenerli in giro durante il runtime) e usare la tua conoscenza del risultato per eliminare i casi impossibili. È piuttosto noioso riprovare un calcolo per il quale già conosci la risposta!

Lavorare in Agda, e l'utilizzo di prodotti naturali, invece di stringhe (perché sono più semplici):

open import Data.Nat 
open import Relation.Binary.PropositionalEquality 
open import Data.Bool 

_==_ : ℕ -> ℕ -> Bool 
zero == zero = true 
suc n == suc m = n == m 
_ == _ = false 

==-refl : forall n -> (n == n) ≡ true 
==-refl zero = refl 
==-refl (suc n) = ==-refl n 


fromProp : forall {n m} -> n ≡ m -> (n == m) ≡ true 
fromProp {n} refl = ==-refl n 

-- we have ways of making you talk 
toProp : forall {n m} -> (n == m) ≡ true -> n ≡ m 
toProp {zero} {zero} refl = refl 
toProp {zero} {suc m}() 
toProp {suc n} {zero}() 
toProp {suc n} {suc m} p = cong suc (toProp {n}{m} p) 

In linea di massima penso che si potrebbe fare questo lavoro in Haskell utilizzando singletons, ma perché preoccuparsi? Non usare Booleans!

+1

Questa è la risposta giusta, ma temo che questo non sia fattibile in Haskell al momento. In Haskell 'n, m' non può essere eliminato poiché hanno un' Simbolo' opaco di tipo '. Potremmo fare affidamento sull'istanza 'KnownSymbol n', tuttavia ciò consente solo di recuperare il nome del simbolo come una stringa a livello di valore, il che non aiuta. – chi

+1

@chi Sì, questo è quello che stavo cercando di ottenere quando ho detto "è necessario avere i valori in fase di esecuzione". Il tipo specificato nella domanda non è soddisfacente in Haskell, avresti bisogno di parametri di tipo 'Sing x' e' Sing y' lì dentro. –

+0

@BenjaminHodgson: ma anche se avessi parametri 'Sing x' e' Sing y', non sono sicuro (per 'Symbol's) che posso ricevere su di essi. – Cactus

Problemi correlati