[Haskell-cafe] Newbie questions
David Menendez
zednenem at psualum.com
Fri Jul 2 22:33:13 EDT 2004
Crypt Master writes:
>From what I can see, a key difficulty you're having is with the
"evolvepopulation" function. You've given it the type a -> a, which
pretty much requires it to be an identity function, because it's not
allowed to make any assumptions about the values it takes.
To make things easier to read, try defining types for Population and
Individual (they can always be generalized later).
> type Individual = Int
> type Population = [Individual]
Then you want
> evolve :: Population -> Population
It looks like you're defining evolution as the composition of mutate,
cross, and select, but got tripped up by the order of evaluation.
Specifically, "mutate cross select p" is the same as "((mutate cross)
select) p", which probably isn't what you want.
If you have:
> mutate :: Population -> Population
> cross :: Population -> Population
> select :: Population -> Population
Then you could define
> evolve p = mutate (cross (select p))
>
> -- alternative:
> -- evolve = mutate . cross . select
Starting from an initial population, you want to generate a sequence by
iterating evolve, starting from an initial population. Haskell provides
a function "iterate" for this purpose, or you can define your own.
> gaSolutionSpace :: Population -> [Population]
> gaSolutionSpace p = p : gaSolutionSpace (evolve p)
>
> -- alternative:
> -- gaSolutionSpace = iterate evolve
Note that the type you want is Population -> [Population].
Now, we get to the problem. You were trying
take 5 gaSolutionSpace [1,2,3,4,5]
But take :: Int -> [a] -> [a]. That means the second argument has to be
a list, not a function which produces a list. But that's easily solved
by some parentheses:
take 5 (gaSolutionSpace [1,2,3,4,5])
Or you can define another function:
> generate :: Int -> Population -> [Population]
> generate n p = take n (gaSolutionSpace p)
>
> -- alternative:
> -- generate n = take n . gaSolutionSpace
I found it helpful to remember that you can think of a function f :: a
-> b -> c as taking two arguments of types a and b and returning a
result c, or as taking a single argument of type a and returning a
result of type b -> c. Once you become comfortable with partial
application, a lot of Haskell code starts to make more sense.
--
David Menendez <zednenem at psualum.com> <http://www.eyrie.org/~zednenem/>
More information about the Haskell-Cafe
mailing list