Haskell에서 유형이 지워 집니까?


13

Haskell은“일반적인 기능”이라는 개념을 가지고 있는데, 이는 일반적인 lisp와 공통점을 가진 경험이없는 일반적인 lisp와 비슷한 점이 있습니다. 이것은 to_string모든 유형의 문자열 표현을 정의하는 일반 기능을 정의 할 수 있음을 의미합니다 . 물론 특수한 경우에는 시설을 정의해야하지만 to_string서명이 인 함수가 α → string있습니다.

OCaml과 마찬가지로 Haskell에서 유형이 지워 집니까? 그렇다면 Haskell의“일반 기능”의 구현은 유형이 동적이므로 삭제되지 않는 일반적인 lisp의 구현과 어떻게 다릅니 까?

구현 세부 사항은 컴파일러마다 다르지만 대부분 또는 모든 구현에 공통적 인 조항이있을 수 있음을 이해합니다.


5
아마도 사소한 유형의 함수를 정의 할 수는 없습니다 a -> String. 과 같은 유형 제약 조건이있을 가능성이 큽니다 Show a => a -> String.
DJG

답변:


16

지금까지의 대답은 오해의 소지가 있습니다.

"파라 메트릭"과 "애드혹 오버로드"다형성 간에는 구별이 필요합니다. 파라 메트릭은 "모든 유형에 대해 균일하게 작동 함"을 의미하는 반면, "애드혹"(Simon이 다형성이라고 함)은 유형에 따라 구현을 변경합니다.

둘 다의 예 reverse :: [a] -> [a]는 파라 메트릭 show :: Show a => a -> String이며 "ad-hoc"과부하입니다.

추상적 직관을 더 원한다면, "소유하다"또는 "생각하다"와 같이 모든 객체에 대해 "작동하는"자연 언어 동사의 클래스를 고려하는 것이 도움이된다고 생각합니다. 우리가 말하는 것을 열 수 있어야합니다. '나무를 여는 것'과 같은 의미는 없지만 '문을 생각하고', '문을 열'수 있습니다. 더 많은 "열기"는 "창을 열려면"과 "고객 서비스로 불만 표를 여는 것"과 같이 "임시 다형성"은 매우 다른 두 가지입니다. 이것이 강제로 보인다면 잊어 버리십시오! 그것은 나를 위해 작동합니다.

그러나 둘 다 컴파일 타임에 해결되며 실제로는 "지워집니다". Modulo 다양한 GHC 확장 및 템플릿 Haskell 등. 실제로 유형 컴파일 타임에 지워지고 런타임에 검사되지 않습니다.

매개 변수 적으로 다형성 함수는 모든 유형에 대해 동일하게 작동하므로 한 코드 만 생성하면되지만 컴파일러는 컴파일시 특정 유형의 "유형 분류"함수 버전을 실행해야하는 시점을 결정합니다. 이것이 또한 유형 클래스 당 유형 당 하나의 인스턴스 제한과 해당 "newtype"해결 방법이 존재하는 이유입니다.

구현은 SPJs 교과서 와 Wadler and Blotts 논문 유형 유형에 자세히 설명되어 있습니다 .


답변을 삭제해야한다고 생각하십니까?
Simon Bergot

아니요, 정확한 어휘를 쓰지 않았다는 경고가 표시됩니다.)
Kris

GHC가 유형을 지울 수있는 이유에 대해 조금 확장 할 수 있습니까? 주요한 타이핑 덕분입니까?
Simon Bergot

2
일반적으로 런타임에 파라 메트릭 다형성 함수는 한 번만 존재할 수 있으며 가상 디스패치 방법을 통해 임시 다형성 함수를 호출하거나 각 코드에 대해 모든 코드가 별도로 생성되어 정적으로 링크 된 호출이 가능합니다. 언어 관점에서 구현이 정확합니다 (하스켈에는 다형성 유형이 없으며 GHC forall확장으로 만 만들 수 있음 ).
Jan Hudec

유형을 지울 수없는 GHC 확장이 있습니까? 과부하는 정적이고 의존성이 전혀없는 유형으로 생각할 수 없음
Daniel Gratzer

1

경고 : CS의 내 배경이 그리 강하지 않기 때문에 항상 올바른 어휘를 사용하지 않을 수 있으며 어떤 점에서는 틀릴 수 있습니다. 어쨌든, 여기 내 이해가 있습니다 :

제네릭을 다형성과 혼동하고 있다고 생각합니다.

일반 유형 List<Foo>은 다른 유형을 매개 변수로 사용하고보다 다양한 유형 검사를 허용하는 유형을 설명하는 데 사용됩니다.

haskell의 일반적인 함수는 다음과 같습니다 count:: List a -> Int. 모든 유형의 목록을 허용하고 요소 수를 리턴합니다. 구현은 하나뿐입니다.

일반적으로 List를 정의 할 때는 T에 대해 아무 것도 가정 할 수 없습니다. T 만 저장하고 되돌릴 수 있습니다.

당신의 to_string함수는 서로 다른 상황에서 다르게 행동 할 수단 다형성 기능입니다. haskell에서는 typeclass를 사용하여 형용사처럼 작동합니다.

함수 Show를 정의 하는 typeclass가 show :: a -> String있습니다.

형식이 형식 클래스를 Foo구현할 때는 Show의 정의를 제공해야합니다 show. 이 타입은 Show(와 같이 Show a => a -> whatever) 한정자를 필요로하는 함수에 사용될 수 있습니다 . Haskell은 유형을 지울 수 없습니다. 이러한 함수는 함수의 올바른 구현을 찾아야하기 때문입니다 show.


일반적인 lisp에서 다형성 함수를 "일반 함수"IIRC라고하며 동일한 (혼란스러운) 어휘를 사용했습니다. 당신의 대답은 유용하고 마지막 논증은 꽤 설득력이 있습니다. .-)
user40989

"구현 된 것은 하나뿐"입니다. 말이되는 것만은 확실하지만, 무한히 많은 가능성이 있습니다. 타입 a → b의 함수는 | b | ^ | a | 가능한 구현 (Bool → Bool 유형의 기능 수를 고려하십시오) 및 목록에는 크기 제한이 없습니다.
Jon Purdy 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.