jeudi 9 février 2017

Nested list resulting from do statement

As part of the following code, I have two 'populations' (genetic algorithm). Each population is comprised of many partial solutions. Combining a partial solution from each population produces a whole solution, for which I am attempting to calculate a fitness. The fitness assigned to each individual is initially calculated by matching it with a random partial solution in the opposite population:

generateInitial :: (MonadRandom m)
                => EvolutionParameters
                -> Domain
                -> (Domain -> X -> Y -> Float)
                -> m ([(X, Float)], [(Y, Float)])
generateInitial ep@(EvolutionParameters popSize _ _ _) d fitnessFunction = do
  (xs, ys) <- genPopulations popSize
  (
      initialFitnessXs ep d fitnessFunction (xs, ys)
    , initialFitnessYs ep d fitnessFunction (xs, ys)
  )

-- Returns: m [(X, Float)]
initialFitnessXs ep d@(Domain cs ts _) fnf (xs, ys) = do
  yPicks <- replicateM (length ys) (pick ys)
  return $ map (\(x, y) -> (x, fnf d x y)) $ zip xs yPicks

-- Returns: m [(Y, Float)]
initialFitnessYs ep d@(Domain cs ts _) fnf (xs, ys) = do
  xPicks <- replicateM (length xs) (pick xs)
  return $ map (\(x, y) -> (p, fnf d x y)) $ zip xPicks ys

However, the type this returns from generateInitial is not m ([(Xs, Float)], [(Ys, Float)]) as I would have thought, but nests the lists deeper, resulting in:

• Couldn't match type ‘[(X, Float)]’
                 with ‘(X, Float)’
  Expected type: m ([(X, Float)], [(Y, Float)])
    Actual type: m ([[(X, Float)]], [[(Y, Float)]])

What causes this further nesting, and how could I avoid it?




Aucun commentaire:

Enregistrer un commentaire