((a-> b)-> b)-> ab 유형의 함수를 실현하는 방법이 있습니까?


18

제안 (P -> Q) -> QP \/ Q동일합니다.

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 = ???

그런

from . to = id그리고 to . from = id?


이것이 불가능하다는 것은 분명하지만, 아마도 내가 틀렸다. 그렇다면 유용한 시작점은 다형성 유형의 함수 ((a -> b) -> b)가 동형 일 a수 있다는 것입니다 g f = f someHardcodedA. 가능한 유일한 구현 방법은 입니다.
amalloy

1
@amalloy 또 다른 가능한 구현이 있습니다 :g = const someHardcodedB
Fyodor Soikin

아 물론 이죠 이 중 하나입니다 a또는 b. 맞는 말이다.
amalloy

1
Haskell이 call / cc를 가지고 있다면 to f = callcc (\k -> k (Right (f (\a -> k (Left a)))))작동합니다. (이것은 그 의미에 대한 유효한 고전적 증거입니다.)
benrg

답변:


14

제안 (P -> Q) -> QP \/ Q동일합니다.

이것은 고전적인 논리에서는 사실이지만 건설적인 논리에서는 그렇지 않습니다.

건설적인 논리에서 우리는 제외 된 법칙을 가지고 있지 않습니다 . 즉, "P는 참이거나 P는 참이 아닙니다"로 생각을 시작할 수 없습니다.

고전적으로 우리는 다음과 같이 추론합니다

  • P가 참이면 (즉, 우리는 ( x :: P)를) 반환 Left x합니다.
  • P가 거짓이면 Haskell에서 우리는 nx :: P -> Void기능을 할 것 입니다. 그리고 absurd . nx :: P -> Q(우리는 모든 종류의 피크 수 있습니다, 우리는 가지고 Q) 주어진 전화 f :: (P -> Q) -> Q)absurd . nx유형의 값을 얻을 Q.

문제는 유형의 일반적인 기능이 없다는 것입니다.

lem :: forall p. Either p (p -> Void)

일부 콘크리트 유형의 경우 예를 들어 Bool거주자가 있으므로

lemBool :: Either Bool (Bool -> Void)
lemBool = Left True -- arbitrary choice

그러나 일반적으로 우리는 할 수 없습니다.


9

아니요, 불가능합니다. 특별한 경우를 고려하십시오 Q = Void.

Either P Q그러면 Either P Voidis is is is is is is a is is에 대한 동형 P입니다.

iso :: P -> Either P Void
iso = Left

iso_inv :: Either P Void -> P
iso_inv (Left p)  = p
iso_inv (Right q) = absurd q

따라서 함수 용어가 있다면

impossible :: ((P -> Void) -> Void) -> Either P Void

우리는 또한 용어를 가질 수 있습니다

impossible2 :: ((P -> Void) -> Void) -> P
impossible2 = iso_inv . impossible

Curry-Howard 서신에 따르면, 이것은 직관 논리 의 율법이 될 것입니다 .

((P -> False) -> False) -> P

그러나 위의 이중 부정 제거는 직관 논리 에서 입증하기가 불가능한 것으로 알려진 이중 부정 제거 입니다. (우리가 고전 논리 에서 그것을 증명할 수 있다는 사실 은 관련이 없습니다.)

(최종 참고 사항 : 이것은 Haskell 프로그램이 종료되었다고 가정합니다. 물론 undefined결과를 반환하지 않기 위해 무한 재귀 및 이와 유사한 방법을 사용하면 Haskell의 모든 유형에 거주 할 수 있습니다.)


4

아니요, 가능하지는 않지만 약간 미묘합니다. 문제는 입력 변수이다 a하고는 b보편적으로 정량화된다.

to :: ((a -> b) -> b) -> Either a b
to f = ...

a그리고 b보편적으로 정량화. 호출자는 어떤 유형인지 선택하므로 두 유형의 값만 만들 수는 없습니다. 이것은 Either a bargument를 무시하고 type 값을 만들 수 없다는 것을 의미합니다 f. 그러나 사용 f도 불가능합니다. 유형 a과 유형을 모르면 에 전달할 b유형의 값을 만들 수 없습니다 . 유형이 보편적으로 정량화 될 때 이용 가능한 정보가 충분하지 않습니다.a -> bf

Haskell에서 동 형사상이 작동하지 않는 한, 그 제안이 건설적인 직관 론 논리에서 동등하다고 확신하십니까? 하스켈은 고전적인 연역적 논리를 구현하지 않습니다.


2

다른 사람들이 지적했듯이, 우리는 배제 된 중간의 법칙이 없기 때문에 불가능합니다. 좀 더 명확하게 설명하겠습니다. 우리가 가지고 있다고 가정

bogus :: ((a -> b) -> b) -> Either a b

우리는 설정했습니다 b ~ Void. 그럼 우리는 얻는다

-- chi calls this `impossible2`.
double_neg_elim :: ((a -> Void) -> Void) -> a
bouble_neg_elim f = case bogus f of
             Left a -> a
             Right v -> absurd v

이제 특정 제안에 적용되는 제외 된 중간 법칙의 이중 부정을 증명해 봅시다 .

nnlem :: forall a. (Either a (a -> Void) -> Void) -> Void
nnlem f = not_not_a not_a
  where
    not_a :: a -> Void
    not_a = f . Left

    not_not_a :: (a -> Void) -> Void
    not_not_a = f . Right

그래서 지금

lem :: Either a (a -> Void)
lem = double_neg_elim nnlem

lema내가 선택한 Turing 머신 구성이 중단된다는 제안을 인코딩 할 수 있기 때문에 분명히 존재할 수 없습니다 .


그것이 lem충분한 지 확인합시다 :

bogus :: forall a b. ((a -> b) -> b) -> Either a b
bogus f = case lem @a of
  Left a -> Left a
  Right na -> Right $ f (absurd . na)

0

이것이 논리면에서 유효한지 또는 귀하의 동등성에 어떤 의미가 있는지는 알 수 없지만 그렇습니다. 하스켈에서 그러한 함수를 작성할 수 있습니다.

를 구성하려면 또는 값이 Either a b필요합니다 . 값 을 구성 할 방법이 없지만 호출 할 수 있는 값을 반환하는 함수가 있습니다. 이를 위해, 우리는 변환하는하는 기능을 제공 할 필요가 에 가장 함수가 반환하는 일정을에서,하지만 종류의 주어는 우리가 할 수 알을 . 그 얻으려면 값을,이 순환 논리가되도록 우리는 그것을 이전보다 다른 방법을 만들 수 없습니다 - 우리는 간단하게 작성하여 그것을 해결할 수 fixpoint를 :abababbb

to :: ((a -> b) -> b) -> Either a b
to f = let x = f (\_ -> x) in Right x
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.