[Haskell-cafe] Using Product Algebraic types

Stefan Holdermans sholderm at students.cs.uu.nl
Sun Jul 4 12:44:49 EDT 2004


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




More information about the Haskell-Cafe mailing list