
Hi My question is how do I select or work with product Alhebraic types ? Let you give you some context: I need to be able to work with a list of items whos structure is onyl partially know. That is at the level of this module I dont care about what rest of it is. So I have this: type Fitness = Integer data Population a = Population [Fitness a] Hopefully this reads Population is constructed using the Population constructor and is a list who elements each conists a fitness value and some other value. Since I cant do poloymorphioc types with synonyms I went with the data type. My current task is to build a roulette wheel distribution of the fitness value. Basically I want to build and incremental summing of the fitness value so that each individual is paired with its upper range like so Population [10 x, 20 y, 30 z] New Population = [10 x, 20+10 y, 30+30 z] My first thought was a list comprehension: rwList :: Population -> Population rwList (Population popList) = Population [ (rwListSum i) | i <- popList] rwListSum :: [a] -> [a] rwListSum (fitness individual) = (fitness*2, individual) ingoring for a minute that this wont achieve the above goal, I immediatly ran into the issue of how do I represent in the inner portion of the Population List, i.e "Fitness a". "(fitness individual)" doesnt work ? I tried treating it as 2 normal arguments, but of course how can I return it then ... ? A function can only return one thing. If its not a tuple then it wont work. Hence my question of how you represent product types ? I did come up with one idea, that is of making the internal part a type on its own so now I have this: type Fitness = Integer data InternalIndividual a = InternalIndividual Fitness a data Population a = Population [InternalIndividual a] ... rwList :: Population -> Population rwList (Population popList) = Population [ (rwListSum i) | i <- popList] rwListSum :: InternalIndividual -> InternalIndividual rwListSum (InternalIndividual fitness individual) = (InternalIndividual fitness*2 individual) To my surpirse this compiles. I have been able to fully test it yet though. So is there a way to do this without a extra type ? Is there a better way to represent this ? Thanks for your time, PS Sorry for all the dumb questions, I always find asking better than just wondering for ages. _________________________________________________________________ MSN 8 with e-mail virus protection service: 2 months FREE* http://join.msn.com/?page=features/virus

Crypt Master, CM> I need to be able to work with a list of items whos CM> structure is onyl partially know. That is at the level CM> of this module I dont care about what rest of it is. CM> So I have this: < type Fitness = Integer < data Population a = Population [Fitness a] Well, first of all: this will not compile. You've declared Fitness to be an synonym of Integer and Integer is not a parametric data type, i.e. it has kind *. In your definition for Population, however, you apply Fitness to a type argument. This will give you a kind error. CM> Hopefully this reads Population is constructed using CM> the Population constructor and is a list who elements CM> each conists a fitness value and some other value. So, no, it does not. I guess this is what you want:
type Fitness = Integer data Population a = Population [(Fitness, a)] deriving (Show)
Now Population constructs a Population value from a list of which the elements are pairs of a Fitness value and a value of a specified type a. CM> Since I cant do poloymorphioc types with synonyms I CM> went with the data type. Well, actually, you can:
type Population' a = [(Fitness, a)]
but type synonyms have the restriction that they cannot be partially applied. Another option might be
newtype Population'' a = Population'' [(Fitness, a)]
which is only slightly different from the definition above involving data. CM> My current task is to build a roulette wheel CM> distribution of the fitness value. Basically I want to CM> build and incremental summing of the fitness value so CM> that each individual is paired with its upper range CM> like so CM> CM> Population [10 x, 20 y, 30 z] CM> New Population = [10 x, 20+10 y, 30+30 z] This can be accomplished by
rw :: Population a -> Population a rw (Population xs) = Population (scanl1 f xs) where f (n, a) = (+ n) `pair` id
where pair is the maps a pair of functions to a function on pairs:
pair :: (a -> c) -> (b -> d) -> (a, b) -> (c, d) f `pair` g = h where h (a, b) = (f a, g b)
A little test:
main :: IO () main = print $ rw (Population [(10, 2), (20, 3), (30, 5)])
This prints: "Population [(10,2),(30,3),(60,5)]". HTH, Stefan
participants (2)
-
Crypt Master
-
Stefan Holdermans