I have a problem which I can solve with OO organization, but I want to know how to do it properly in Haskell.

I have a search optimization problem in which there are a lot of individual fitness functions which combine scores to give an overall fitness level.

Each fitness function will be associated with data, both initial data to configure it, and a cache that it maintains.

So I could have something like this:

data Fitness = Fit1 SomeData1
             | Fit2 SomeData2
             | Fit3 SomeData3

-- this function would evaluate the fitness of a particular
-- result of type 'S' (in my case, a partially-constructed
-- musical composition)
evaluate :: Fitness -> S -> (Fitness,Double)

-- something like this would have to be written for
-- every sub-type of "Fitness"
evaluate (Fit1 d) s = (Fit1 d',v)
  where
    (d',v) = evaluate1 d s

evaluate1 :: SomeData1 -> S -> (SomeData1,Double)


Is there a better way to do this?

D