Failed to deduce (Eq a) by adding Eq to typeclass

I am new to Haskell and I encountered this error while trying to compile Frag .

src/AFRPVectorSpace.hs:51:25: Could not deduce (Eq a) arising from a use of `/=' from the context (VectorSpace va) bound by the class declaration for `VectorSpace' at src/AFRPVectorSpace.hs:(32,1)-(53,23) Possible fix: add (Eq a) to the context of the class declaration for `VectorSpace' In the expression: nv /= 0 In the expression: if nv /= 0 then v ^/ nv else error "normalize: zero vector" In an equation for `normalize': normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector" where nv = norm v 

Relevant Code:

 class Floating a => VectorSpace va | v -> a where zeroVector :: v (*^) :: a -> v -> v (^/) :: v -> a -> v negateVector :: v -> v (^+^) :: v -> v -> v (^-^) :: v -> v -> v dot :: v -> v -> a norm :: v -> a normalize :: v -> v v ^/ a = (1/a) *^ v negateVector v = (-1) *^ v v1 ^-^ _ = v1 ^+^ v1 -- (negateVector v2) norm v = sqrt (v `dot` v) normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector" where nv = norm v 

My first guess: I need to add Deriving Eq or something like that, but I'm not sure exactly what I need to do.

+4
source share
3 answers

I would suggest that you need to have class (Eq a,Floating a) => VectorSpace va | v -> a class (Eq a,Floating a) => VectorSpace va | v -> a if you want to use /= for a in your default implementations.

The second alternative is to remove normalize from the class and make it a normal function.

The third alternative is to add a constraint to the normalize type, making it Eq a => v -> v .

+6
source

Prior to ghc 7.4.1, the class Num a had a restriction Eq a , so any Num a also had Eq a . Floating a has a restriction of Num a , so all Floating a also had Eq a .

However, this changed in 7.4.1, where the Eq a constraint (as well as the Show a constraint) was removed from the Num class. This is why the code no longer works.

So, the solution to the problem is exactly what the aylator gave: add the Eq a constraint explicitly to the VectorSpace class.

Alternatively, you can download an older version of ghc (e.g. 6.8 based on wiki notes). This version should compile the program without any changes. You can then update the code to make it work with a newer version of ghc if you want to.

+5
source

This is not an answer to your question (which has already been answered), but since it is not easy to insert blocks of code in comments, I will add it as an β€œanswer”.

You might prefer to use type families instead of functional dependencies. Type families allow you to do everything you can do with functional dependencies, as well as much more. Here is one way to write your code using type families. It is very similar to your source code, except that your type a variable has been replaced with a "call" to a function of type Metric v (the best name I could name without attention.)

 {-# LANGUAGE TypeFamilies, FlexibleContexts #-} class Floating (Metric v) => VectorSpace v where type Metric v zeroVector :: v (*^) :: Metric v -> v -> v (^/) :: v -> Metric v -> v negateVector :: v -> v (^+^) :: v -> v -> v (^-^) :: v -> v -> v dot :: v -> v -> Metric v norm :: v -> Metric v normalize :: Eq (Metric v) => v -> v v ^/ a = (1/a) *^ v negateVector v = (-1) *^ v v1 ^-^ _ = v1 ^+^ v1 -- (negateVector v2) norm v = sqrt (v `dot` v) normalize v = if nv /= 0 then v ^/ nv else error "normalize: zero vector" where nv = norm v 

Here are some useful links:

+1
source

All Articles