답변:
Go의 유형 유추에 관한 이 StackOverflow 답변을 참조하십시오 . 나는 Go 나 자신에 익숙하지 않지만이 답변을 기반으로 한 일방향 "유형 추론"처럼 보입니다 (일부 C ++ 용어를 빌리기 위해). 그것은 당신이 가지고 있다면 :
x := y + z
그런 다음의 유형을 x
알아 냄으로써 의 유형 이 추론되는데 y + z
, 이는 컴파일러에 대해 비교적 사소한 일입니다. 이렇게하려면 유형 y
및 z
필요 알려진 할 선험적 :이 유형의 주석을 통해 수행하거나 할당 된 리터럴에서 유추 할 수있다.
대조적으로, 대부분의 기능적 언어에는 변수의 유형을 도출하기 위해 모듈 (또는 추론 알고리즘이 로컬 인 경우 함수) 내에서 가능한 모든 정보를 사용하는 유형 추론이 있습니다. 복잡한 추론 알고리즘 (예 : Hindley-Milner)은 종종 배후에 어떤 형태의 통일 ( 일부 방정식 풀기와 같은)을 포함합니다. 예를 들어, Haskell에서 다음과 같이 쓰는 경우 :
let x = y + z
다음 하스켈 타입 단지 추측 할 수 x
있지만, 또한 y
하고 z
당신이 그들에 추가를 수행하고 있다는 사실에 기초 간단합니다. 이 경우 :
x :: Num a => a
y :: Num a => a
z :: Num a => a
(소문자 는 C ++와 같은 다른 언어에서는 흔히 "일반"이라고 a
하는 다형성 유형 을 나타냅니다 .이 Num a =>
부분은 유형 지원에 추가 개념이 있음을 나타내는 제약 조건a
입니다.)
다음은 재귀 함수를 정의 할 수있는 고정 소수점 결합기입니다.
let fix f = f (fix f)
우리는 어디에도 타입을 f
지정하지 않았으며, 타입을 지정하지도 않았지만 fix
Haskell 컴파일러는 자동으로 다음을 알아낼 수 있습니다.
f :: t -> t
fix :: (t -> t) -> t
이것은 말합니다 :
f
는 임의의 유형 t
에서 동일한 유형 으로의 함수 여야합니다 t
.fix
유형의 매개 변수를 수신하고 유형 t -> t
의 결과를 리턴하는 함수입니다 t
.Go의 타입 추론은 매우 제한적이고 매우 간단합니다. 하나의 언어 구성 (변수 선언)에서만 작동하며 단순히 오른쪽 유형을 가져 와서 왼쪽 변수의 유형으로 사용합니다.
Haskell의 형식 유추는 어디에서나 사용할 수 있으며 전체 프로그램의 형식을 유추하는 데 사용할 수 있습니다. 통일을 기반으로합니다. 즉 (개념적으로) 모든 유형이 "한 번에"추론되고 서로 영향을 줄 수 있습니다. Go에서 유형 정보는 변수 선언의 오른쪽에서 왼쪽으로 만 흐를 수 있습니다. 다른 방향으로 절대 변하지 않으며 변수 선언 밖에서는 절대로; Haskell에서는 유형 정보가 전체 프로그램을 통해 모든 방향으로 자유롭게 흐릅니다.
그러나 Haskell의 형식 시스템은 너무 강력하여 형식 유추가 실제로 형식을 유추 하지 못할 수 있습니다 (또는 더 정확하게는 형식을 항상 유추 할 수 있도록 제한을 설정해야 함). Go의 타입 시스템은 매우 단순하고 (서브 타이핑이없고, 파라 메트릭 다형성이 없음) 추론이 제한되어있어 항상 성공합니다.
x
,y
,z
동일Num
, 에릭 형하지만 그들은 여전히 할 수있다Integer
S,Double
S,Ratio Integer
로 ... 하스켈 다른 typeclasses에 대한 숫자 유형 사이의 임의의 선택을 기꺼이 만이 아니다.