Reputation: 371
I'm not able to figure out what this error msg means. I want to define the function distance for the data type below... I do NOT want to use any GHC extensions.. even if the code is ugly, want to understand the error better, before I move on to using the extensions. Can someone please let me know what this error means and how I can get rid of this.
class Vector v where
distance :: v -> v -> Double
-- doesn't make sense, but WTH...
newtype OneD1 a = OD1 a
deriving (Show)
instance Vector (Maybe m) where
distance _ _ = 5.6
instance Vector (OneD1 m) where
distance (OD1 x1) (OD1 x2) = x2-x1
Prelude> :reload
[1 of 1] Compiling Main ( VectorTypeClass.hs, interpreted )
VectorTypeClass.hs:33:33:
Couldn't match expected type `Double' with actual type `m'
`m' is a rigid type variable bound by
the instance declaration
at C:\Users\byamm\Documents\Programming\Haskell\Lab\Expts\VectorTypeClass\VectorTypeClass.hs:32:10
Relevant bindings include
x2 :: m
(bound at C:\Users\byamm\Documents\Programming\Haskell\Lab\Expts\VectorTypeClass\VectorTypeClass.hs:33:27)
x1 :: m
(bound at C:\Users\byamm\Documents\Programming\Haskell\Lab\Expts\VectorTypeClass\VectorTypeClass.hs:33:18)
distance :: OneD1 m -> OneD1 m -> Double
(bound at C:\Users\byamm\Documents\Programming\Haskell\Lab\Expts\VectorTypeClass\VectorTypeClass.hs:33:4)
In the first argument of `(-)', namely `x2'
In the expression: x2 - x1
Failed, modules loaded: none.
Prelude>
Upvotes: 1
Views: 59
Reputation: 116139
instance Vector (OneD1 m) where
This promises that (OdeD1 m)
is a vector, for any m
. Including OneD1 String
, etc.
distance (OD1 x1) (OD1 x2) = x2-x1
Here we try to apply -
on two values of type m
, which could be absolutely anything. There are two issues here:
m
might not be a numeric type -- GHC is not reporting this error, at the moment.m
, but distance should produce a Double
. This is the error GHC is reporting.You need to restrict m
to some numeric type, so that you can use -
, and that type must admit a conversion to Double
, otherwise you can't satisfy the distance
signature.
One trivial way is:
instance Vector (OneD1 Double) where
distance (OD1 x1) (OD1 x2) = x2-x1
Another could be:
instance Real m => Vector (OneD1 m) where
distance (OD1 x1) (OD1 x2) = realToFrac (x2-x1)
Upvotes: 5