문제

Haskell의 유형 시스템에 대한 일반적인 질문이 있습니다. 나는 그것에 익숙해 지려고 노력하고 있으며 다음과 같은 기능을 가지고 있습니다.

getN :: Num a => a
getN = 5.0 :: Double

이것을 컴파일하려고하면 다음과 같은 오류가 발생합니다.

Couldn't match expected type `a' against inferred type `Double'
  `a' is a rigid type variable bound by
      the type signature for `getN' at Perlin.hs:15:12
In the expression: 5.0 :: Double
In the definition of `getN': getN = 5.0 :: Double

이것을 이해하면서 함수는 클래스 NUM의 유형을 "반환"하도록 설정됩니다. 이 클래스에서 더블은 (http://www.zvon.org/other/haskell/outputprelude/num_c.html), 그래서 나는이 경우 더블을 "반환"해도 괜찮을 것이라고 기대했을 것이다.

누군가 이것을 설명해 주시겠습니까?

도움이 되었습니까?

해결책

서명이있는 함수 Num a => a 일할 것으로 예상됩니다 어느 수업을 입력하십시오 Num. 구현 5.0 :: Double 그냥 작동합니다 하나 유형이 아닙니다 모두 클래스의 유형이므로 컴파일러가 불만을 제기합니다.

일반적인 기능의 예는 다음과 같습니다.

square :: (Num a) => a -> a
square x = x * x

이것은 효과가 있습니다 어느 a Num. 복식, 정수 및 사용하려는 다른 숫자에 대해 작동합니다. 그로 인해 매개 변수를 클래스에 필요로하는 일반 유형 서명이있을 수 있습니다. Num. (수업을 입력하십시오 Num 함수는 곱셈을 사용하기 때문에 필요합니다 *, 거기에 정의됩니다)

다른 팁

STH의 답변에 추가하려면 : Haskell은 객체 지향적이지 않습니다. 사실이 아닙니다 Double 서브 클래스입니다 Num, 당신은 a를 반환 할 수 없습니다 Double 다형성을 반환하겠다고 약속한다면 Num 당신이 할 수있는 것처럼, Java.

당신이 쓸 때 getN :: Num a => a 당신은 완전히 다형성 인 값을 반환 할 것을 약속합니다 Num 강제. 효과적으로 이것은 당신이에서만 함수 만 사용할 수 있음을 의미합니다. Num 다음과 같은 유형 클래스 +, *, - 그리고 fromInteger.

체크 아웃 실존 적으로 정량화 된 유형.

그것을 해결하는 한 가지 방법은 새 데이터 유형을 정의하는 것입니다.

data NumBox = forall n. Num n => NumBox n

너는 필요할거야 -XExistentialQuantification 이것을 작동시키기 위해.

이제 당신은 같은 것을 쓸 수 있습니다

getN :: NumBox
getN = NumBox (5.0 :: Double)

당신은 또한 a를 정의 할 수 있습니다 NumBox-리스트로

let n3 = [NumBox (4.0 :: Double), NumBox (1 :: Integer), NumBox (1 :: Int) ]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top