Haskell 내에서 특정 유형을 반환합니다
-
20-09-2019 - |
문제
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) ]