Propuestas (P -> Q) -> Q
y P \/ Q
son equivalentes.
¿Hay alguna manera de presenciar esta equivalencia en 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 = ???
tal que
from . to = id
y to . from = id
?
((a -> b) -> b)
es isomórfica paraa
: la única implementación posible esg f = f someHardcodedA
.g = const someHardcodedB
a
o bien ob
. Tiene sentido.to f = callcc (\k -> k (Right (f (\a -> k (Left a)))))
funcionaría. (Esta es una prueba clásica válida de la implicación.)Respuestas:
Esto es cierto en la lógica clásica, pero no en la lógica constructiva.
En la lógica constructiva no tenemos la ley del medio excluido , es decir, no podemos comenzar a pensar con "o P es verdadero o P no es verdadero".
Clásicamente razonamos como:
x :: P
)), entonces devuelveLeft x
.nx :: P -> Void
función. Luegoabsurd . nx :: P -> Q
(podemos alcanzar cualquier tipo de pico, tomamosQ
) y llamar dadof :: (P -> Q) -> Q)
conabsurd . nx
para obtener el valor de tipoQ
.El problema es que no hay una función general de un tipo:
Para algunos tipos concretos hay, por ejemplo,
Bool
está habitada para que podamos escribirpero de nuevo, en general no podemos.
fuente
No, es imposible Considere el caso especial donde
Q = Void
.Either P Q
es entoncesEither P Void
, que es isomorfo aP
.Por lo tanto, si tuviéramos un término de función
también podríamos tener un término
Según la correspondencia de Curry-Howard, esto sería una tautología en la lógica intuicionista :
Pero lo anterior es la eliminación de la doble negación, que es bien sabido que es imposible de probar en la lógica intuicionista , de ahí una contradicción. (El hecho de que podamos probarlo en la lógica clásica no es relevante).
(Nota final: esto supone que nuestro programa Haskell finalizará. Por supuesto, usando la recursión infinita
undefined
y formas similares para evitar devolver un resultado, podemos habitar cualquier tipo en Haskell).fuente
No, no es posible, pero es un poco sutil. El problema es que las variables de tipo
a
yb
están universalmente cuantificadas.a
yb
están universalmente cuantificados. La persona que llama elige qué tipo son, por lo que no puede simplemente crear un valor de cualquier tipo. Esto implica que no puede simplemente crear un valor de tipoEither a b
mientras ignora el argumentof
. Pero usarf
también es imposible. Sin saber qué tiposa
y québ
son, no puede crear un valor de tipoa -> b
para pasarf
. Simplemente no hay suficiente información disponible cuando los tipos se cuantifican universalmente.En cuanto a por qué el isomorfismo no funciona en Haskell, ¿estás seguro de que esas proposiciones son equivalentes en una lógica constructivista intuicionista? Haskell no implementa una lógica deductiva clásica.
fuente
Como otros han señalado, esto es imposible porque no tenemos la ley del medio excluido. Déjame pasar por eso un poco más explícitamente. Supongamos que tenemos
y nos propusimos
b ~ Void
. Entonces tenemosAhora, demostremos la doble negación de la ley del medio excluido aplicada a una proposición específica .
Y ahora
lem
claramente no puede existir porquea
puede codificar la proposición de que cualquier configuración de máquina de Turing que elija se detendrá.Verifiquemos que
lem
sea suficiente:fuente
No tengo idea de si esto es válido en términos de lógica, o qué significa para su equivalencia, pero sí, es posible escribir dicha función en Haskell.
Para construir un
Either a b
, necesitamos una
o unb
valor. No tenemos ninguna forma de construir una
valor, pero tenemos una función que devuelve un valorb
que podríamos llamar. Para hacer eso, necesitamos proporcionar una función que convierta una
en ab
, pero dado que los tipos son desconocidos, en el mejor de los casos podríamos hacer una función que devuelva una constanteb
. Para obtener eseb
valor, no podemos construirlo de otra manera que antes, por lo que esto se convierte en un razonamiento circular, y podemos resolverlo simplemente creando un punto de fijación :fuente