2014-07-08 1 views
0

나는 하스켈에서 다음 함수를 컴파일 할 수 있습니다 얻을 수 있으며하스켈 기능은 컴파일 오류가

addVector :: (Num a) => (a, a) -> (a, a) -> (a, a) 
addVector (a, b) (c, d) = (a + c, b + d) 

작동하지만 두 기능 사이의 유일한 차이는있다 기능

addVector3 :: (Float a) => (a, a) -> (a, a) -> (a, a) 
addVector3 (a, b) (c, d) = (a + c, d + b) 

을 다음과 같은 사항에 대해 컴파일 오류

: 입력

오류 (NumFloat로 변경)

`Float' is applied to too many type arguments 
In the type signature for `addVector3': 
addVector3 :: Float a => (a, a) -> (a, a) -> (a, a) 
+6

'Num'은 유형이 아닌 _class_ 유형입니다. '플로트 '는 _ 유형 _입니다. 그것들을 혼합하고 일치시킬 수는 없습니다. – Xeo

답변

6

설명을 확대하여 Float은 형식이고 Num은 typeclass입니다. 그게 무슨 뜻 이죠? 음, Float은 하나의 구체적인 유형입니다 : 부동 소수점 숫자. Num a은 "Num이라는 요구 사항을 충족하는 모든 유형 a"을 의미합니다. Num의 예로는 Int, Float 등이 있습니다.

그래서 "이 함수는 어떤 유형의 숫자라면이 함수는 모든 유형을 처리합니다."라고 말하는 것이 합리적입니다. 그러나 "이 함수는 모든 유형을 처리합니다. 그 유형은 구체적으로 Float "입니다 (이는 의미가있는 경우 (Float a) => (a, a) -> (a, a) -> (a, a)을 해석해야 할 것입니다).

addVector :: (Float, Float) -> (Float, Float) -> (Float, Float) 

을 또는 당신은 반복 Float,()를 입력하는 당신이 경우 타이어, 이것에 대한 타입 동의어를 정의 할 수 있습니다 : 대신, 당신은 단순히 같은, "이 기능은 Float의 취급"말할 수

type Vector = (Float, Float) 
addVector :: Vector -> Vector -> Vector 
+0

Haskell에 대해 충분한 경험이있는 사람은 눈이 멀어 보이지만 컴파일러가 더 유용한 메시지를 낼 수 있는지 궁금해 할 것입니다. 해당 형식의 비트에서 형식 이름이 유효한 지점이 있습니까? –

+0

@MatthewWalton [명백하게] (http://stackoverflow.com/a/12022602/625403) 그렇게하는 데 사용됩니다. – amalloy

+0

문제는 두 가지 오류가 있다는 것입니다. 먼저 'Float a'는 'Float'이 인수를 취하지 않으므로 종류 오류가 발생합니다. 이 오류를 간과하면 두 번째 유형 오류, 즉 유형이 클래스로 사용 된 오류를 발견 할 수 있습니다. – augustss