Каков корреспондент Карри-Говарда двойного отрицания a
; (a -> r) -> r
или (a -> ⊥) -> ⊥
, или оба?
Оба типа могут быть закодированы в Haskell следующим образом, где ⊥
кодируется как forall b. b
.
p1 :: forall r. ((a -> r) -> r)
p2 :: (a -> (forall b. b)) -> (forall b. b)
Бумага Wadler 2003, а также реализация в Haskell, похоже, принимает первое, в то время как некоторые другая литература (например, this), похоже, поддерживает последнее.
Мое настоящее понимание заключается в том, что последнее верно. Мне трудно понять прежний стиль, так как вы можете создать значение типа a
из forall r. ((a -> r) -> r)
, используя чистое вычисление:
> let p1 = ($42) :: forall r. (Int -> r) -> r
> p1 id
42
который, как представляется, противоречит интуиционистской логике, вы не можете получить a
из ¬¬a
.
Итак, мой вопрос: can p1
и p2
оба будут рассматриваться как корреспондент Карри-Говарда ¬¬a
? Если да, то как тот факт, что мы можем построить p1 id :: a
, взаимодействует с интуиционистской логикой?
Я нашел более четкое кодирование преобразования в/из двойного отрицания, для удобства обсуждения. Благодаря @user2407038!
{-# LANGUAGE RankNTypes #-}
to_double_neg :: forall a. a -> (forall r. (a->r)->r)
to_double_neg x = ($x)
from_double_neg :: forall a. (forall r. (a->r)->r) -> a
from_double_neg x = x id