Propozycje (P -> Q) -> Q
i P \/ Q
są równoważne.
Czy istnieje sposób, aby być świadkiem tej równoważności w Haskell:
from :: Either a b -> ((a -> b) -> b)
from x = case x of
Left a -> \f -> f a
Right b -> \f -> b
to :: ((a -> b) -> b) -> Either a b
to = ???
takie, że
from . to = id
i to . from = id
?
((a -> b) -> b)
jest izomorficzna dlaa
: jedyną możliwą implementacją jestg f = f someHardcodedA
.g = const someHardcodedB
a
albob
. Ma sens.to f = callcc (\k -> k (Right (f (\a -> k (Left a)))))
by działało. (Jest to ważny klasyczny dowód implikacji.)Odpowiedzi:
Dotyczy to logiki klasycznej, ale nie logiki konstruktywnej.
W logice konstruktywnej nie mamy prawa wykluczonego środka , tzn. Nie możemy rozpocząć myślenia od „albo P jest prawdą, albo P nie jest prawdą”.
Klasycznie rozumujemy:
x :: P
)), to zwróćLeft x
.nx :: P -> Void
funkcję. Następnieabsurd . nx :: P -> Q
(możemy szczyt wszelkiego rodzaju, bierzemyQ
) i wywołać danef :: (P -> Q) -> Q)
zabsurd . nx
aby uzyskać wartość typuQ
.Problem polegający na tym, że nie ma ogólnej funkcji typu:
Dla niektórych konkretnych typów istnieją, np. Są
Bool
zamieszkane, więc możemy pisaćale ogólnie nie możemy.
źródło
Nie, to niemożliwe. Rozważ szczególny przypadek, w którym
Q = Void
.Either P Q
jest wtedyEither P Void
, co jest izomorficzneP
.Stąd, gdybyśmy mieli pojęcie funkcji
moglibyśmy również mieć termin
Według korespondencji Curry-Howarda byłaby to tautologia w intuicyjnej logice:
Ale powyższe to eliminacja podwójnej negacji, o której wiadomo, że jest niemożliwa do udowodnienia w logice intuicyjnej - stąd sprzeczność. (Fakt, że możemy to udowodnić w logice klasycznej, nie ma znaczenia).
(Uwaga końcowa: zakłada się, że nasz program Haskell zakończy się. Oczywiście, używając nieskończonej rekurencji
undefined
i podobnych sposobów, aby faktycznie uniknąć wyniku, możemy zamieszkać w Haskell dowolnego typu).źródło
Nie, nie jest to możliwe, ale jest nieco subtelne. Problem polega na tym, że zmienne typu
a
ib
są powszechnie ilościowo.a
ib
są powszechnie obliczane ilościowo. Dzwoniący wybiera, jakiego rodzaju są, więc nie można po prostu utworzyć wartości żadnego z tych typów. Oznacza to, że nie można po prostu utworzyć wartości typuEither a b
, ignorując argumentf
. Ale używanief
jest również niemożliwe. Bez wiedzy o typacha
i typachb
nie można utworzyć wartości typu, którąa -> b
należy przekazaćf
. Po prostu nie ma wystarczającej ilości informacji, gdy typy są powszechnie kwantyfikowane.Jeśli chodzi o to, dlaczego izomorfizm nie działa w Haskell - czy jesteś pewien, że te twierdzenia są równoważne w konstruktywnej intuicyjnej logice? Haskell nie implementuje klasycznej logiki dedukcyjnej.
źródło
Jak zauważyli inni, jest to niemożliwe, ponieważ nie mamy prawa wykluczonego środka. Pozwól, że przejdę przez to nieco bardziej wyraźnie. Załóżmy, że mamy
i ustawiamy
b ~ Void
. Potem dostaniemyTeraz udowodnijmy podwójną negację prawa wykluczonego środka w odniesieniu do konkretnego zdania .
Więc teraz
lem
najwyraźniej nie może istnieć, ponieważa
może zakodować twierdzenie, że każda konfiguracja maszyny Turinga, którą wybiorę, zostanie zatrzymana.Sprawdźmy, czy
lem
to wystarczy:źródło
Nie mam pojęcia, czy jest to poprawne logicznie, czy co oznacza dla twojej równoważności, ale tak, możliwe jest napisanie takiej funkcji w Haskell.
Aby zbudować
Either a b
, potrzebujemy albo wartości,a
albob
wartości. Nie mamy żadnego sposobu na skonstruowaniea
wartości, ale mamy funkcję, która zwraca funkcjęb
, którą moglibyśmy wywołać. Aby to zrobić, musimy podać funkcję, która konwertuje ana
na ab
, ale biorąc pod uwagę, że typy nie są znane, moglibyśmy w najlepszym wypadku stworzyć funkcję, która zwraca stałąb
. Aby uzyskać tęb
wartość, nie możemy jej skonstruować w żaden inny sposób niż wcześniej, więc staje się to okrągłym rozumowaniem - i możemy to rozwiązać, po prostu tworząc punkt stały :źródło