이 모델에서 타입 클래스는 어떻게 맞습니까?
짧은 대답은 그렇지 않습니다.
강제 다형성, 유형 클래스 또는 임시 다형성을위한 다른 메커니즘을 언어에 도입 할 때마다 직면하는 주요 디자인 문제는 일관성 입니다.
기본적으로 유형이 지정된 프로그램이 단일 해석을 갖도록 유형 클래스 결정이 결정적이어야합니다. 예를 들어, 동일한 범위에서 동일한 유형에 대해 여러 인스턴스를 제공 할 수 있으면 다음과 같이 모호한 프로그램을 작성할 수 있습니다.
class Blah a where
blah : a -> String
instance Blah T where
blah _ = "Hello"
instance Blah T where
blah _ = "Goodbye"
v :: T = ...
main :: IO ()
main = print (blah v) -- does this print "Hello" or "Goodbye"?
컴파일러가 선택한 인스턴스의 선택에 따라 또는 blah v
중 하나 "Hello"
와 같을 수 있습니다 "Goodbye"
. 따라서 프로그램의 의미는 프로그램의 구문에 의해 완전히 결정되는 것이 아니라 컴파일러가 만드는 임의의 선택에 의해 영향을받을 수 있습니다.
이 문제에 대한 Haskell의 솔루션은 각 유형에 각 유형 클래스마다 최대 하나의 인스턴스가 있어야한다는 것입니다. 이를 보장하기 위해 최상위 수준에서만 인스턴스 선언을 허용하고 모든 선언을 전체적으로 볼 수 있습니다. 이렇게하면 모호한 인스턴스 선언이 만들어지면 컴파일러에서 항상 오류를 알릴 수 있습니다.
그러나 전 세계에 선언을 선언하면 의미의 구성이 깨집니다. 복구하기 위해 할 수있는 일은 프로그래밍 언어에 대한 정교한 의미 를 부여하는 것입니다. 즉, Haskell 프로그램을보다 잘 작동하고보다 구성적인 언어로 번역하는 방법을 보여줄 수 있습니다.
이것은 실제로 타입 클래스를 컴파일하는 방법을 제공합니다. 일반적으로 하스켈 서클에서 "증거 번역"또는 "사전 전달 변환"이라고하며 대부분의 하스켈 컴파일러의 초기 단계 중 하나입니다.
타입 클래스는 프로그래밍 언어 디자인이 순수한 타입 이론과 어떻게 다른지에 대한 좋은 예입니다. 타입 클래스는 정말 멋진 언어 기능이지만 증명 이론적 관점에서 보면 악의적입니다. 이것이 Agda에 타입 클래스가 전혀없는 이유이며 Coq가 휴리스틱 추론 인프라의 일부로 만드는 이유입니다.