简体   繁体   中英

Haskell Num Instance

I am new to Haskell so I apologize if I am overlooking something basic, but I am creating a Coord type that has three parameters: Position, Vector, and Scalar. Coord must be an instance of Num and must have specific implemented methods in it. I believe I have what I need already, but I'm assuming I'm missing something basic because I get an error based on the Num instance.

My code:

data Position x y = Position (x, y)
data Vector x y = Vector (x, y)
data Scalar n = Scalar n
data Coord x y n = Coord (Position x y, Vector x y, Scalar n)

instance Num Coord where
    negate (Position (x, y)) = Position (-x, -y)
    negate (Vector (x, y)) = Vector (-x, -y)
    (+) (Vector (a, b) Position (x, y)) = Position (x+a, y+b)
    (+) (Vector (a, b) Vector (c, d)) = Vector (c+a, d+b)
    (+) (Scalar x Scalar y) = Scalar (x+y)
    (*) (Vector (a, b) Scalar c) = Vector (a*c, b*c)
    (*) (Position (x1, y1) Position (x2, y2)) = (x1*x2) + (y1*y2)
    (*) (Scalar x Scalar y) = Scalar (x*y)
    (-) (Vector (a, b) Position (x, y)) = Position (x-a, y-b)
    (-) (Position (x1, y1) Position (x2, y2)) = Vector (x2-x1, y2-y1)
    (-) (Scalar x Scalar y) = Scalar (x-y)
    abs (Position (x, y)) = Scalar sqrt((x*x)+(y*y))
    abs (Vector (x, y)) = Scalar sqrt((x*x)+(y*y))
    signum _ = error "undefined"
    fromInteger _ = error "undefined"

The error I get:

Expecting three more arguments to ‘Coord’
The first argument of ‘Num’ should have kind ‘*’,
  but ‘Coord’ has kind ‘* -> * -> * -> *’
In the instance declaration for ‘Num Coord’

Any clarification on how to use Num would be much appreciated (I'm assuming that is what's responsible for the error)

Thank you.

After looking into the suggestions I finally cam up with a solution that works.

data Coord = Position (Double, Double) | Vector (Double, Double) | Scalar Double deriving (Show)

instance Num Coord where
    negate (Position (x, y)) = Position (-x, -y)
    negate (Vector (x, y)) = Vector (-x, -y)
    (+) (Vector (a, b)) (Position (x, y)) = Position (x+a, y+b)
    (+) (Position (x, y)) (Vector (a, b)) = Position (x+a, y+b)
    (+) (Vector (a, b)) (Vector (c, d)) = Vector (c+a, d+b)
    (+) (Scalar x) (Scalar y) = Scalar (x+y)
    (*) (Vector (a, b)) (Scalar c) = Vector (a*c, b*c)
    (*) (Scalar c) (Vector (a, b)) = Vector (a*c, b*c)
    (*) (Position (x1, y1)) (Position (x2, y2)) = Scalar((x1*x2) + (y1*y2))
    (*) (Scalar x) (Scalar y) = Scalar (x*y)
    (-) (Vector (a, b)) (Position (x, y)) = Position (x-a, y-b)
    (-) (Position (x, y)) (Vector (a, b)) = Position (a-x, b-y)
    (-) (Position (x1, y1)) (Position (x2, y2)) = Vector (x2-x1, y2-y1)
    (-) (Scalar x) (Scalar y) = Scalar (x-y)
    abs (Position (x, y)) = Scalar (sqrt((x*x)+(y*y)))
    abs (Vector (x, y)) = Scalar (sqrt((x*x)+(y*y)))
    signum _ = error "undefined"
    fromInteger _ = error "undefined"

Hopefully this helps anyone in the future that is making the same mistakes as me.

Your problem in a word: parentheses.

instead of

negate Position (x, y) = Position (-x, -y)

do

negate (Position (x, y)) = Position (-x, -y)

The former implicitly implies that negate is a function which takes two arguments - the Position value constructor and (x,y) , rather than a single argument of type Position , since it parses it as

((negate Position) (x,y)) = ...

Your other function definitions have the same problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM