나는 Hindley-Milner 유형의 추론 시스템 이 작동 하는 작은 람다 미적분학 컴파일러에서 일하고 있으며 이제는 링크 된 코드가 아닌 재귀 렛을 지원 하므로 Turing을 완성하기에 충분해야합니다 .
이제 문제는 목록을 지원하는 방법 또는 이미 목록을 지원하는지 여부를 알지 못하므로 인코딩 방법을 찾아야한다는 것입니다. 형식 시스템에 새 규칙을 추가하지 않고도 규칙을 정의하고 싶습니다.
내가 목록을 생각할 수있는 가장 쉬운 방법 x
은 null
(또는 빈 목록) 또는 x
의 목록과 목록이 모두 포함 된 쌍 입니다 x
. 그러나 이렇게하려면 제품 및 합계 유형이라고 생각하는 쌍 및 / 또는을 정의 할 수 있어야합니다.
이 방법으로 쌍을 정의 할 수있는 것 같습니다 :
pair = λabf.fab
first = λp.p(λab.a)
second = λp.p(λab.b)
때문에 pair
유형을 할 것이다 a -> (b -> ((a -> (b -> x)) -> x))
, 통과 후, 말을 int
하고는 string
,이 유형 뭔가를 얻을 것 (int -> (string -> x)) -> x
한 쌍의 표현이 될 것이다, int
하고 string
. 여기서 나를 귀찮게하는 것은 그것이 쌍을 나타내는 경우 논리적으로 동등하지 않거나 제안을 암시한다는 것 int and string
입니다. 그러나 (((int and string) -> x) -> x)
제품 유형을 함수의 매개 변수로만 사용할 수있는 것처럼와 같습니다. 이 답변이 문제를 해결하는 것 같지만 그가 사용하는 기호가 무엇을 의미하는지 전혀 모른다. 또한 이것이 실제로 제품 유형을 인코딩하지 않으면 위의 쌍에 대한 내 정의로 수행 할 수없는 제품 유형으로 할 수있는 일이 있습니까 (n- 튜플도 같은 방식으로 정의 할 수 있음을 고려할 때)? 그렇지 않다면, 이것은 당신이 의미 만 사용하여 (AFAIK) 결합을 표현할 수 없다는 사실과 모순되지 않습니까?
또한 합계 유형은 어떻습니까? 어떻게 든 함수 유형을 사용하여 인코딩 할 수 있습니까? 그렇다면 목록을 정의하기에 충분합니까? 아니면 내 유형 시스템을 확장하지 않고도 목록을 정의하는 다른 방법이 있습니까? 그렇지 않은 경우 가능한 한 간단하게 유지하려면 어떤 변경을해야합니까?
나는 컴퓨터 프로그래머이지만 컴퓨터 과학 자나 수학자가 아니며 수학 표기법을 읽는 데 상당히 나쁘다는 것을 명심하십시오.
편집 : 지금까지 구현 한 기술적 이름이 무엇인지 잘 모르겠지만 기본적으로 위에 링크 한 코드 만 사용합니다.이 코드는 응용 프로그램, 추상화 및 변수에 대한 규칙을 사용하는 제약 조건 생성 알고리즘입니다. Hinley-Milner 알고리즘과 기본 유형을 가져 오는 통합 알고리즘에서 예를 들어, 표현식 \a.a
은 type을 생성 a -> a
하고 표현식 \a.(a a)
은 발생 확인 오류를 발생시킵니다. 이 외에도 정확히 let
규칙이 아니라 의사 코드와 같은 재귀 전역 함수를 정의 할 수있는 동일한 효과가있는 함수가 있습니다.
GetTypeOfGlobalFunction(term, globalScope, nameOfFunction)
{
// Here 'globalScope' contains a list of name-value pair where every value is of class 'ClosedType',
// meaning their type will be cloned before unified in the unification algorithm so that they can be used polymorphically
tempType = new TypeVariable() // Assign a dummy type to `tempType`, say, type 'x'.
// The next line creates an scope with everything in 'globalScope' plus the 'nameOfFunction = tempType' name-value pair
tempScope = new Scope(globalScope, nameOfFunction, tempType)
type = TypeOfTerm(term, tempScope) // Calculate the type of the term
Unify(tempType, type)
return type
// After returning, the code outside will create a 'ClosedType' using the returned type and add it to the global scope.
}
코드는 기본적으로 평소와 같이 용어의 유형을 얻지 만 통합하기 전에 더미 유형으로 정의되는 함수의 이름을 유형 범위에 추가하여 자체적으로 재귀 적으로 사용할 수 있습니다.
편집 2 : 방금 필요없는 목록을 정의하기 위해 재귀 유형이 필요하다는 것을 깨달았습니다.
let func = \x -> (func x)
.