0
votes

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.

2
There are very many issues with this code. You shouldn't try to write large amounts of code at once like this; now you're getting errors and you don't know which part of the code you've written is at fault!Lynn
The error you're getting refers to the instance Num Coord where line: you probably want something like instance (Num x, Num y, Num n) => Num (Coord x y n) where. This is because Num expects a fully "filled-out" type as its argument: you can write an instance Num Int or Num (Maybe Int), but not Num Maybe or Num [].Lynn
But really, your design looks very weird, and I wouldn't even bother fixing this; what are you actually trying to achieve, what kind of code do you want to write with this? You say you're "creating a Coord function that has three parameters [...]" but clearly you've defined Coord as a type, not a function.Lynn
It is confusing to me too. A Coord has a Position, a Vector and a Scalar inside of it (which would add up to a five dimensional value)?David Young
Don't get frustrated, but at the moment your problem is not with Num typeclass. Before getting there, you should create better types (Position,Vector,Scalar,Coord) as the currrent definitions clearly do not represent what you expect them to.zudov

2 Answers

2
votes

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.

0
votes

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.