[Haskell-cafe] Using Product Algebraic types

Crypt Master cryptmaster at hotmail.com
Sun Jul 4 15:31:39 EDT 2004


Man, your a genius :-) Thanks for the help , still dijesting it. 
Interestingly enough I was playing with how to use sacnl1 just before I got 
this message from you, but as you mentioned I was battling with "kind" 
errors so I never got to test my idea besides on paper.

Am I correct in assuming that your definition of Popoulation is now using 
tuple and not product types ? If so it it better to use tuples ? In the book 
the craft of func programing, it shows product type examples like this:

data People = Person Name Age
type Name = String
type Age = Int

Later it shows polymoric definitions like this:

data Pairs a = Pr a a

You mentioned that I had applied the polymorphic type "a" to Fitness, but 
but in the above example of person and people they have done the exactly 
what I did ? Used a space to seperate elements. So I am a little confused as 
to why mine didnt work.

Regarding the use of newtype and data I saw another thread on this and I 
will use that get some insights on the differences.

Your "rw" took some following until I realised currying was invovled *grin*

 > rw (Population xs) =  Population (scanl1 f xs)
 >                         where f (n, a) = (+ n) `pair` id

Can I ask one question, I am not concerned with performance at this point, 
but what sort of overhead does a function like id have. It seems unneccesary 
to me ( I am not critising your solution, I am vert thankfull for your help 
) in a large populations you will  land up doing a fair amount of extra but 
simple "reductions" ( I hope thats the right word. ) just to "copy" the 
unkown "a". Or does it have to be a function for some reason and so you had 
to use "id" ?



----Original Message Follows----
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> 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)]".



MSN 8 helps eliminate e-mail viruses. Get 2 months FREE*. 

More information about the Haskell-Cafe mailing list