8

Gibt es eine Verbindung zwischen propositional und promoted Gleichheit?Gibt es eine Verbindung zwischen `a: ~: b` und` (a: == b): ~: True`?

Lassen Sie uns sagen, ich habe

prf :: x :~: y 

in Rahmen für einige Symbol s; von Pattern-Matching auf sie Refl ist, kann ich das in

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

wie diese Transformation:

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

Aber was ist die andere Richtung? Wenn ich versuche,

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

dann alles, was ich bekommen ist

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

Sicher, 'toProp _ = unsafeCoerce Refl'. 'sameSymbol' ist auf diese Weise definiert, also bezweifle ich, dass Sie es besser machen können. – user3237465

+1

Sie könnten auch 'toProp Refl = fromJust $ sameSymbol (Proxy :: Proxy x) (Proxy :: Proxy y)' schreiben, aber das ist nur geringfügig besser als mit 'unsafeCoerce'. – user2407038

Antwort

8

Ja, zwischen den beiden Darstellungen gehen kann (vorausgesetzt, die Umsetzung der :== korrekt ist), aber es erfordert Berechnung.

Die benötigten Informationen sind nicht im Boolean selbst enthalten (it's been erased to a single bit); Sie müssen es wiederherstellen. Dies beinhaltet die Befragung der beiden Teilnehmer des ursprünglichen Booleschen Gleichheitstests (was bedeutet, dass Sie sie zur Laufzeit behalten müssen) und die Verwendung Ihrer Kenntnis des Ergebnisses, um die unmöglichen Fälle zu eliminieren. Es ist ziemlich mühsam, eine Berechnung erneut durchzuführen, für die Sie die Antwort bereits kennen!

Arbeiten in Agda und Naturals statt Strings (weil sie einfacher):

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) 

Grundsätzlich denke ich, diese Arbeit in Haskell mit Singletons machen könnte, aber warum die Mühe machen? Verwenden Sie keine Booleschen Werte!

+1

Das ist die richtige Antwort, aber ich befürchte, dass dies momentan in Haskell nicht machbar ist. In Haskell 'n, m 'kann nicht eliminiert werden, da sie einen undurchsichtigen Typ' Symbol' haben. Wir könnten uns auf die 'KnownSymbol n'-Instanz verlassen, die es jedoch nur erlaubt, den Namen des Symbols als Zeichenfolge auf der Werteebene wiederherzustellen, was nicht hilft. – chi

+1

@chi Ja, genau das habe ich versucht, als ich sagte "Du musst die Werte zur Laufzeit haben". Der in der Frage angegebene Typ ist in Haskell nicht erfüllbar, Sie müssten Parameter vom Typ 'Sing x' und' Sing y' drin haben. –

+0

@BenjaminHodgson: Aber selbst wenn ich 'Sing x' und' Sing y' Parameter hätte, bin ich mir nicht sicher (für 'Symbol's), dass ich auf sie rekurrieren kann. – Cactus