왜 유도적인 데이터 유형을 금지 유형을 다음과 같`데이 나쁜=C(나쁜 a>a)`형식 재귀가 앞에서 발생->?
-
11-12-2019 - |
문제
Agda 설명서 유도적인 데이터 유형 및 패턴 매칭 상태:
을 위해 정규화,유도 발생을 표시해야합에서 엄격히 긍정적 위치.예를 들어,다음과 같은 데이터 형식이 허용되지 않:
data Bad : Set where bad : (Bad → Bad) → Bad
이 있기 때문에 부정의 발생에 나쁜 인수를 생성자입니다.
이것이 왜 필요한 요구 사항에 대한 유도적인 데이터 유형에 있습니까?
해결책
데이터 입력을 했다는 것은 특별한에서는 그의 매립 턴 lambda 생합니다.
data Bad : Set where
bad : (Bad → Bad) → Bad
unbad : Bad → (Bad → Bad)
unbad (bad f) = f
자의 방법을 참조하십시오.리콜되지 않은 람다 수학은 이러한 조건:
e := x | \x. e | e e'
우리는 정의할 수 있는 번역 [[e]]
에서 형식화되지 않은 람다 수학 용어를 Agda 약관의 유형 Bad
(지에 Agda):
[[x]] = x
[[\x. e]] = bad (\x -> [[e]])
[[e e']] = unbad [[e]] [[e']]
이제 사용할 수 있습니다 당신의 마음에 드는 종료되지 않는 형식화되지 않은 람다 용어를 생산하는 종료되지 않는 용어의 형식 Bad
.예를 들어,우리는 번역할 수 있는 (\x. x x) (\x. x x)
비 종료하는 표현의 형식 Bad
아래:
unbad (bad (\x -> unbad x x)) (bad (\x -> unbad x x))
지만 이 유형이 일어났는 특히 형태로 편리하게 이를 위해 인수 될 수 있고,일반화의 비트와 함께 작동하는 모든 데이터 형식으로 부정적인 항목의 재귀.
다른 팁
는 방법을 예를 들어 이러한 데이터를 입력할 수 있습 우리가 살고 어떤 형식에서 주어진 터너,D.A.(2004-07-28), 총형 프로그래밍,sect.3.1 페이지에 758 원칙 2:형 재귀어야 합 공변."
만들자가 더 정교한 예을 사용하여 구현합니다.우리가 시작할 것이다"나쁜"재귀적인 데이터 입력
data Bad a = C (Bad a -> a)
을 구성하고 Y 연결 에서 그것없이 모든 다른 형태의 재귀.즉,이러한 데이터를 입력할 수 있습 우리를 구성하는 모든 종류의 재귀,또는 거주하여 모든 유형 무한한 재귀.
Y 연결에서 형식화되지 않은 람다 수학으로 정의
Y = λf.(λx.f (x x)) (λx.f (x x))
의 열쇠는 우리가 적용 x
하에서 자신 x x
.에서 입력한 언어 이것은 바로,가능한가 없기 때문에 유효한 유형 x
할 수 있다.그러나 우리의 Bad
데이터 형식은 이 모듈을 추가/제거 생성자:
selfApp :: Bad a -> a
selfApp (x@(C x')) = x' x
그 x :: Bad a
, 우리는 할 수 있습을 풀을 생성자와 적용 기능 안 x
자체입니다.일단 우리는 작업을 수행하는 방법을 알고,그것은 쉽게 구성 Y 연결:
yc :: (a -> a) -> a
yc f = let fxx = C (\x -> f (selfApp x)) -- this is the λx.f (x x) part of Y
in selfApp fxx
Note 도 selfApp
도 yc
는 재귀,이 없적화의 기능을 자체입니다. 재귀에서만 나타나 우리의 재귀적 데이터를 입력합니다.
우리는 확인할 수 있는 건 참으로 연결자가 무엇을 해야 합니다.우리가 만들 수 있는 무한 루프:
loop :: a
loop = yc id
또는 계산이 말 GCD:
gcd' :: Int -> Int -> Int
gcd' = yc gcd0
where
gcd0 :: (Int -> Int -> Int) -> (Int -> Int -> Int)
gcd0 rec a b | c == 0 = b
| otherwise = rec b c
where c = a `mod` b