[Haskell-cafe] Using Product Algebraic types
David Menendez
zednenem at psualum.com
Sun Jul 4 16:27:53 EDT 2004
Crypt Master writes:
> Am I correct in assuming that your definition of Popoulation is now
> using tuple and not product types ?
Actually, tuples *are* product types. They just have some syntactic
sugar defined for them in the language.
For example,
Main> ('x',5) :: (Char,Int)
('x',5)
Main> ('x',5) :: (,) Char Int
('x',5)
> 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.
Pairs has kind * -> *. Given a type, it constructs a new type.
(Pr has type a -> a -> Pairs a. For any type a, it takes two values of
type a and returns a value of type Pairs a).
Your code looked like:
type Fitness = Integer
data Population a = Population [Fitness a]
The kinds involved are:
Population :: * -> *
Fitness :: *
[] :: * -> *
It's the list type constructor that's causing you problems.
Specifically, what you have is equivalent to:
data Population a = Population ([] (Fitness a))
It's trying to apply a to Fitness, which doesn't work because Fitness is
a type, not a type constructor.
What you need is a single type containing a and Fitness. You could
either declare a new one and use that:
data IndividualWithFitness a = IWF a Fitness
data Population a = Population [IWF a]
-- equivalent to:
-- Population a = Population ([] (IWF a))
Or just use a generic pair type:
data Population a = Population [(a,Fitness)]
-- equivalent to:
-- Population a = Population ([] ((,) a Fitness))
(,) has kind * -> * -> *, so it takes two type arguments ("a" and
"Fitness") and constructs a new one ("(a,Fitness)").
> > 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" ?
You need id if you're using pair, because pair requires two functions.
If that turned out to be a performance bottleneck, you could factor out
pair and write f directly:
rw (Population xs) = Population (scanl1 f xs)
where
f (n,a) (m,b) = (n + m, a)
--
David Menendez <zednenem at psualum.com> <http://www.eyrie.org/~zednenem/>
More information about the Haskell-Cafe
mailing list