
Hi, One reason (there may be more) is as follows: Grigory Sarnitskiy wrote:
class Configuration c where getParticleI :: (Particle p) => c -> Int -> p
This type signature declares that for any type c that has a Configuration instance (and an Int), you can give me back something that is of *any type* p, provided I have a Particle instance for p. So if I was to declare: instance Particle Int Then I should be able to do: x :: Int x = getParticleI someConfigurationItem 6 But...
type Collection p = UArray (Int,Int) Double instance Configuration (Collection p) where getParticleI config i = (1,1,1) :: ParticleC
What you are doing in your instance, however, is always returning a ParticleC, which is a specific type rather than any type that belongs to Particle. There are several ways to solve this. A few examples: 1. Make getParticleI specifically return a ParticleC, rather than the type p. 2. Add a makeParticle function to the particle type-class. If you had: class Particle p where makeParticle :: (Double, Double, Double) -> p Then you could rewrite that last line as: getParticleI config i = makeParticle (1, 1, 1) And then the return would be of any type p that has a Particle instance. 3. Parameterise the collection over the particle, e.g. class Configuration c where getParticleI :: Particle p => c p -> Int -> p But currently Collection is not actually parameterised using the p parameter (the UArray has Double, not Particle), so I can't properly adjust your example for that. Hope that helps, Neil.