Reputation:
I'm in the process of writing a toy (physics) vector library and am having issues with GHC insisting functions should have Integer
s in their type. I want vectors to multiply vectors, as well as scalars (just using *
), and while this was possible by just having Vector
instance Num
I'm now getting errors of the sort:
Couldn't match expected type `Integer' with actual type `Double'
After playing around with the code in order to pin down the problem I've gotten it down to this:
data V a = V a a a deriving (Show, Eq, Functor)
scale a (V i j k) = V (a*i) (a*j) (a*k)
(<.>) = scale
Now if we ask GHCi what type these are we get:
>:t scale
scale :: Num a => a -> V a -> V a
>:t (<.>)
(<.>) :: Integer -> V Integer -> V Integer
Where we certainly don't want <.>
only acting on Integer
s. While this is fixable here by including a type signature for <.>
, I would like to know what's actually going on.
Upvotes: 7
Views: 204
Reputation: 10260
You are running into the infamous monomorphism restriction. Another solution would be to specify arguments explicitly:
a <.> v = scale a v
Or add -XNoMonomorphismRestriction
pragma.
Upvotes: 15