I'm trying to learn Haskell and I'm a bit confused by this infamous "rigid type variable" error.
Here's the relevant part of my code:
class Ord v => Vector v where
distance :: v -> v -> Double
-- with FlexibleInstances
instance Vector (Double, Double) where
distance (a,b) (c,d) = -- function definition omitted
data KMeansState v = KMeansState { centroids :: [v] }
test :: [(Double,Double)]
test = [(0,0),(1,1)] :: [(Double,Double)]
initializeState :: Vector v => Int -> KMeansState v
initializeState n = KMeansState test
The specific complaint that the compiler is giving me:
• Couldn't match type ‘v’ with ‘(Double, Double)’
‘v’ is a rigid type variable bound by
the type signature for:
initializeState :: forall v.
Vector v =>
Int -> Double -> KMeansState v
at Chapter06.hs:32:1-61
Expected type: KMeansState v
Actual type: KMeansState (Double, Double)
My understanding is that the compiler is saying my initializeState function needs to be able to return (or whatever the right word is in Haskell) a KMeansState whose type parameter is any type that's an instance of Vector, while the actual implementation of my function will only return one type, namely a KMeansState (Double, Double).
What I'm not clear on is how to get a "concrete" value out of this initializeState function. At some point in the program, I need to give the KMeansState constructor an actual value which will have an actual type, and it seems like the compiler is saying that I can't do that.
I'm further confused by why the code compiles if I hard code the value of the test function into initializeState. That is, this successfully type-checks, even though the value being passed to the KMeansState function should be functionally the same.
class Ord v => Vector v where
distance :: v -> v -> Double
-- with FlexibleInstances
instance Vector (Double, Double) where
distance (a,b) (c,d) = -- function definition omitted
data KMeansState v = KMeansState { centroids :: [v] }
-- test :: [(Double,Double)]
-- test = [(0,0),(1,1)] :: [(Double,Double)]
initializeState :: Vector v => Int -> KMeansState v
initializeState n = KMeansState [(0,0),(1,1)]::[(Double,Double)]
Can someone please clarify what's going on here and how I get this to compile? Thanks!