2010-12-06 4 views
2

저는 하스켈을 처음 접했고 숙제를 위해 계산기를 구현하려고합니다. 나는 두 개의 값으로 나눌 필요가있는 지점에 갇혀 있는데, 그 유형이 추론 될 수 없거나 선언/변환되어야한다는 것이 문제라고 생각합니다. 이 문제를 직접 해결하는 방법을 배우려하고 있지만 길을 가다 보면 통찰력이 도움이 될 것입니다. 여기 haskell division 유형이 일치하지 않습니까?

코드입니다 : 여기
data Value e = OK e | Error String deriving (Eq) 

-- assuming we know how to type e can be shown, i.e. Show e, then 
-- we know how to show a Value e type 
instance (Show e) => Show (Value e) where 
    show (OK x) = (show x) 
    show (Error s) = "ERROR: " ++ s 

type Token = String 
type Result = Value Int 
type Intermediate = [ (Value Int) ] 

-- an algebra is a things that knows about plus and times 
class Algebra a where 
    plus :: a -> a -> a 
    times :: a -> a -> a 
    subtraction :: a -> a -> a 
    division :: a -> a-> a 

-- assuming that we know how to + and * things of type e, (i.e. 
-- we have Num e, then we have algebra's over Value e 
instance (Num e) => Algebra (Value e) where 
    plus (OK x) (OK y) = (OK (x+y)) 
    times (OK x) (OK y) = (OK (x*y)) 
    subtraction (OK x) (OK y) = (OK (x-y)) 
    division (OK x) (OK 0) = (Error "div by 0") 
    division (OK x) (OK y) = (OK (x `div` y)) <-- this is line 44 that it complains about 

가 ghci이 더 코드가

test.hs:44:34: 
    Could not deduce (Integral e) 
     from the context (Algebra (Value e), Num e) 
     arising from a use of `div' at test.hs:44:34-42 
    Possible fix: 
     add (Integral e) to the context of the instance declaration 
    In the first argument of `OK', namely `(x `div` y)' 
    In the expression: (OK (x `div` y)) 
    In the definition of `division': 
     division (OK x) (OK y) = (OK (x `div` y)) 

test.hs를 통해 내가 프로그램을 실행하려고 오류이다, 나는 거라 생각 명확성을 위해 제외하되, 그렇지 않은 경우 항상 편집 할 수 있습니다.

+0

이것은 질문이 아니어야합니다 .. – Omnipotent

답변

8
div :: (Integral a) => a -> a -> a 
(/) :: (Fractional a) => a -> a -> a 

Num a 어느 Integral aFractional a (역을 적용했지만, 물론)을 의미하지 않는다. div을 사용하려면 적어도 Integral a 문맥만큼 제한적인 것을 제공해야합니다.

+0

... 나는 이것을 오랫동안 보냈다는 것을 믿을 수 없다. 나는 전자가 사용되는 유형을 제한하려는 모든 잘못된 장소를보고 있었다. 당신은 Num을 지적하면서'인스턴스 (Num e) =>'아마도 테스트 중에 변경을 고려하지 않은 코드의 유일한 행 ... 감사합니다. –

3

divIntegral 값 (표준 서곡에서는 Int 또는 Integer)에서만 작동합니다. FloatDouble/ 연산자를 사용하는 부분을 지원하지만 문제의 근본 원인은 Num 유형 클 래스터가 실제로 모든 종류의 나누기 연산을 요구하지 않는다는 것입니다.

이는 의미가 있습니다. 우리가 곱셈이 돌이킬 수없는 Num의 인스턴스를 만들 수있는 많은 수의 콜렉션이 있습니다. 나누기 연산은 본질적으로 의미가 없습니다.

관련 문제