oneStep EvOptions{..} datum pop =
  if(length matingPool < 2) 
    then return []
    else do
      kids <- replicateM n $ do
        p1 <- fromList matingPool
        p2 <- fromList matingPool
        (c,d) <- crossover eGMC (p1,p2)
        c' <- mayMutate c
        d' <- mayMutate d
        sequence [c',d']
      return $ fst $ L.splitAt ePopSize $ (++) elites $ concat kids
  where
    n = ePopSize `div` 2 + ePopSize `mod` 2 
    e = (*) eElites $ fromIntegral $ length matingPool
    matingPool = foldl (\acc i -> let f = fitness datum i in if(isNaN f) then (i, toRational 0):acc else (i, toRational f):acc) [] pop
    elites = fst $ L.splitAt (ceiling e) $ map fst $ L.sortBy (compare `on` (Down . snd)) $ matingPool
    mr = toRational eMutaRate
    mayMutate e = fromList [(mutate eGMC e, mr), (return e, 1 - mr)]
oneStep EvOptions{..} datum pop =
  if(length matingPool < 2) 
    then return []
    else do
      kids <- replicateM n $ do
        p1 <- fromList matingPool
        p2 <- fromList matingPool
        (c,d) <- crossover eGMC (p1,p2)
        c' <- mayMutate c
        d' <- mayMutate d
        sequence [c',d']
      return $ fst $ L.splitAt ePopSize $ (++) elites $ concat kids
  where
    n = ePopSize `div` 2 + ePopSize `mod` 2 
    e = (*) eElites $ fromIntegral $ length matingPool
    matingPool = foldl (\acc i -> let f = fitness datum i in if(isNaN f) then (i, toRational 0):acc else (i, toRational f):acc) [] pop
    elites = fst $ L.splitAt (ceiling e) $ map fst $ L.sortBy (compare `on` (Down . snd)) $ matingPool
    mr = toRational eMutaRate
    mayMutate e = fromList [(mutate eGMC e, mr), (return e, 1 - mr)]
oneStep EvOptions{..} datum pop =
  if(length matingPool < 2) 
    then return []
    else do
      kids <- replicateM n $ do
        p1 <- fromList matingPool
        p2 <- fromList matingPool
        (c,d) <- crossover eGMC (p1,p2)
        c' <- mayMutate c
        d' <- mayMutate d
        sequence [c',d']
      return $ fst $ L.splitAt ePopSize $ (++) elites $ concat kids
  where
    n = ePopSize `div` 2 + ePopSize `mod` 2 
    e = (*) eElites $ fromIntegral $ length matingPool
    matingPool = foldl (\acc i -> let f = fitness datum i in if(isNaN f) then (i, toRational 0):acc else (i, toRational f):acc) [] pop
    elites = fst $ L.splitAt (ceiling e) $ map fst $ L.sortBy (compare `on` (Down . snd)) $ matingPool
    mr = toRational eMutaRate
    mayMutate e = fromList [(mutate eGMC e, mr), (return e, 1 - mr)]