I'm a bit at a loss as to why the last pattern in prodV in the following doesn't work:
{-# LANGUAGE GADTs #-}
data V a where
V0 :: Float -> V Float
Vn :: [Float] -> V [Float]
prodV :: (Num a) => V a -> V a -> a
prodV (V0 x) (V0 y) = x * y
-- prodV (Vn x) (Vn y) = zipWith (*) x y -- this one works
prodV (Vn xs) (Vn ys) = [ sum $ zipWith (*) xs ys ]
prodV (V0 n) (Vn ys) = map (* n) ys
GHCi 7.8.3 complains:
Couldn't match type ‘Float’ with ‘[Float]’
Inaccessible code in
a pattern with constructor
Vn :: [Float] -> V [Float],
in an equation for ‘prodV’
In the pattern: Vn ys`
Any pointers? thanks in advance
prodV
to work for allNum
types, but theV0
andVn
constructors specifically containFloat
. Secondly, you're saying that thea
inV a
has to be aNum
, butNum a => [a]
is not an instance ofNum
. Looks like you're approaching this problem the wrong way. – bheklilrunV :: V a -> a
that simply unwraps the constructors, but the premise of your function is not correct it seems. Maybe you should considerVn :: [Float] -> V Float
, but that would makeunV :: V a -> a
impossible unless you convert your list ofFloat
s to a singleFloat
in some fashion first. – bheklilrV0 n
has typeV Float
whileVn ns
has typeV [Float]
. They're not the same types, but you specified that they must be the same, in the type forprodV
. Pattern matching on GADT constructors refine the types. – András KovácsNum
functions like*
andsum
, so you specified in your type signature that you wantNum a => V a
. But both constructors toV
are existential, they can't just hold any type of value. The values contained inV0
andVn
aren't just anyNum a => a
, they have to have a specific type. You can't construct a value usingV0
with anything other than aFloat
. Similarly,Vn
must be constructed with a value of type[Float]
. You're trying to tell the compiler that forV0 x
andVn y
,x
andy
have the same type, but by definition they can't. – bheklilr