나는 이것에 대해 조금 생각했습니다. 주요 문제는 일반적으로 다형성 유형의 값이 얼마나 큰지 모른다는 것입니다. 이 정보가 없으면 어떻게 든 정보를 얻어야합니다. 단형 화는 다형성을 전문화하여이 정보를 제공합니다. 권투는 알려진 크기의 표현으로 모든 것을 넣어서 당신을 위해이 정보를 얻습니다.
세 번째 대안은 이러한 정보를 종류별로 추적하는 것입니다. 기본적으로 수행 할 수있는 작업은 각 데이터 크기마다 다른 종류를 도입 한 다음 특정 크기의 모든 유형에 대해 다형성 함수를 정의 할 수 있습니다. 아래에 그러한 시스템을 스케치하겠습니다.
종류타입 생성자κㅏ: : = n: : =|∀ a : κ .ㅏ|α|A × B|A + B|A → Br e fㅏ|P D ( K )|μ α : κ .ㅏ
여기서 높은 수준의 아이디어는 유형의 종류가 메모리에 객체를 배치하는 데 얼마나 많은 단어가 필요한지 알려줍니다. 특정 크기의 경우 특정 크기의 모든 유형에 대해 다형성이 쉽습니다. 모든 유형 (다형성 유형까지도)은 여전히 알려진 크기를 가지므로 컴파일은 C보다 어렵지 않습니다.
분류 규칙은이 영어를 수학으로 바꾸며 다음과 같이 표시됩니다.
α : n ∈ ΓΓ ⊢ α : nΓ , α : n ⊢ A : mΓ ⊢ ∀ α : n .A : m
Γ ⊢ A : nΓ ⊢ B : mΓ ⊢ A × B : n + mΓ ⊢ A : nΓ ⊢ B : nΓ ⊢ A + B : n + 1
Γ ⊢ A : mΓ ⊢ B : nΓ ⊢ A → B : 1Γ ⊢ A : nΓ ⊢ r e fA : 1
Γ ⊢ P a d ( k ) : kΓ , α : n ⊢ A : nΓ ⊢ μ α : n .A : n
따라서 모든 정량자는 당신이 원하는 종류를 제공해야합니다. 마찬가지로, 페어링 것은 언 박스형 (unboxed pair) 타입으로, 메모리 에서 옆에 (C 구조체 타입과 같은)를 배치합니다. 분리 결합은 같은 크기의 두 값을 취한 다음 판별 기 태그에 대한 단어를 추가합니다. 함수는 일반적으로 환경 레코드와 코드에 대한 포인터로 표시되는 클로저입니다.A × Bㅏ비
참조는 흥미 롭습니다. 포인터는 항상 한 단어이지만 모든 크기의 값을 가리킬 수 있습니다. 이를 통해 프로그래머
는 복싱을 통해 임의의 객체에 다형성을 구현할 수 있지만 그렇게하지 않아도
됩니다. 마지막으로, 명시적인 크기가 재생되면 공간을 사용하지만 아무것도하지 않는 패딩 유형을 도입하는 것이 종종 유용합니다. (따라서 int와 한 쌍의 int를 결합하지 않으려면 첫 번째 int를 패딩을 추가하여 객체 레이아웃이 균일해야합니다.)
재귀 유형에는 표준 구성 규칙이 있지만 재귀 발생은 크기가 같아야합니다. 즉, 일반적으로 친절한 작업을 수행하려면 포인터에 고정해야합니다. 예를 들어 목록 데이터 유형은
μ α : 1.r e f( P a d ( 2 ) + i n t × α )
따라서 이것은 빈 목록 값 또는 int 쌍과 다른 연결된 목록에 대한 포인터를 가리 킵니다.
이와 같은 시스템에 대한 유형 검사도 그리 어렵지 않습니다. 더 높은 순위 다형성에 대한 완전하고 쉬운 양방향 유형 검사 기능을 갖춘 Joshua Dunfield와의 ICFP 논문의 알고리즘은 거의 변함없이이 경우에 적용됩니다.