2017-11-23 1 views
1

현재 사용자 정의 유형을 Integral으로 변환 할 수있는 유형을 구현하려고합니다. 색인 또는 가중치). 컴파일러는 toIntegral 내 구현을 불평하지만사용자 정의 유형 생성 : 예상 유형 'b'와 실제 유형 'Int'를 일치시킬 수 없습니다.

import Data.Int 

class Convertible a where 
    toIntegral :: Integral b => a -> b 

data Note = Note Tone Int 

instance Convertible Note where 
    toIntegral (Note t o) = o * 12 + toIntegral t 

이 특정한 경우에 나는 음표가 주어진 옥타브에, 피아노 키보드 키의 인덱스로 변환 할 수 있는지 확인하기 위해 그것을 사용하려면 Note은 내 Convertible typeclass를 따르지 않습니다.

• Couldn't match expected type ‘b’ with actual type ‘Int’ 
    ‘b’ is a rigid type variable bound by 
    the type signature for: 
     num :: forall b. Integral b => Note -> b 
    at src/Note.hs:11:5 
• In the expression: octave * 12 + (num tone) 
    In an equation for ‘num’: 
     num (Note tone octave) = octave * 12 + (num tone) 
    In the instance declaration for ‘Convertible Note’ 
• Relevant bindings include 
    num :: Note -> b (bound at src/Note.hs:11:5) 

는 지금까지 내가 이해, 그것은 내가 Integral => b -> a -> b 수를 제한 할 때 내 toIntegral 함수의 내용이, a -> Int로 평가 간주합니다. 지금은 IntIntegral typeclass를 구현하기 때문에 무엇이 잘못되었는지 이해하지 못하겠습니까?

내가 분명히 잘못하고있는 것을 이해할 수 있습니까?

답변

2

유형 변수는 호출 수신자가 선택하며 호출 수신자는 선택하지 않습니다. 귀하의 경우 toIntegralb을 선택할 수 없습니다. 그 형태에 따르면, 이러한 용도의 모든하므로, 어떠한 통합 b을 반환,

toIntegral (Note t o) :: Int 
toIntegral (Note t o) :: Integer 
toIntegral (Note t o) :: Word32 
-- etc. 

솔루션은 o 변환뿐만 아니라, 즉 Int의 변환하는 것입니다 확인 입력하지 그냥 Int해야합니다.

예를 들어 fromIntegral o은 유형으로 변환 할 수 있으므로 Integral입니다.

어쨌든 toIntegral에 정말로 해당 유형이 필요합니까?

+1

확실하게, 당신은'Integral' 클래스에서'fromIntegral'을 의미합니다. : D – gallais

+0

@ gallais 나는 지금 고쳐야한다고 생각한다. 평소와 같이 숫자 변환은 Haskell에서 약간 까다 롭습니다. 변환을 수행하는 유일한 방법은 'Integer'를 사용하는 것입니다.이 방법은 다소 복잡합니다. 'toEnum'이 그것과 동등하다는 보장이 있는지 궁금합니다. – chi

+2

나는'toIntegral (Note t o) = fromIntegral o * 12 + tontegral t'이 잘 작동 할 것이라고 확신한다. – gallais

관련 문제