Propuestas (P -> Q) -> Qy P \/ Qson 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 = idy to . from = id?

((a -> b) -> b)es isomórfica paraa: la única implementación posible esg f = f someHardcodedA.g = const someHardcodedBao 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 -> Voidfunción. Luegoabsurd . nx :: P -> Q(podemos alcanzar cualquier tipo de pico, tomamosQ) y llamar dadof :: (P -> Q) -> Q)conabsurd . nxpara 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,
Boolestá habitada para que podamos escribirpero de nuevo, en general no podemos.
fuente
No, es imposible Considere el caso especial donde
Q = Void.Either P Qes 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
undefinedy 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
aybestán universalmente cuantificadas.aybestá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 bmientras ignora el argumentof. Pero usarftambién es imposible. Sin saber qué tiposay québson, no puede crear un valor de tipoa -> bpara 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
lemclaramente no puede existir porqueapuede codificar la proposición de que cualquier configuración de máquina de Turing que elija se detendrá.Verifiquemos que
lemsea 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 unao unbvalor. No tenemos ninguna forma de construir unavalor, pero tenemos una función que devuelve un valorbque podríamos llamar. Para hacer eso, necesitamos proporcionar una función que convierta unaen 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 esebvalor, 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