This algorithm sorts a list of Individuals, each with two fitness values, into what's called non-dominated fronts. A non-dominated front is a set of individuals where none of the individuals dominate each other. An individual is said to dominate another if is equal or lower (<=) for all fitness values and lower (<) in at least one fitness value. And so [1,1] dominates both [1,2] and [2,1], but neither of the last two dominate each other. The rank of an individual indicates which front it is a member of. [1,1] would have rank 0; [1,2] and [2,1] would both have rank 1. Non-dominant sorting is a small piece in bigger puzzles such as multi-objective optimization with genetic algorithms. If you are interested in how the algorithm works you can check out Jensen 2003, but I'm completely new to Haskell so I'm sure there's a lot to pick on without understanding squat about the actual algorithm. Here it goes:RankSort.hsmodule RankSort () whereimport qualified Data.Vector as Vimport           Genomeimport           SortUtilsgo :: Stringgo = let vind = Prelude.map toInd [(4,4),(2,3),(4,3),(1,1),(1,3),(2,1),(3,1),(1,1)]         pool = V.fromList vind         cmp x y = indCmpFit x y 0         pool_s = poolSort pool cmp         fronts = V.fromList [V.fromList []]     in show $ rankSort pool_s frontsrankSort :: Pool -> Fronts -> FrontsrankSort pool fronts  | V.length fronts == 1 && V.length (fronts V.! 0) == 0 = rankSort new_pool start_front -- start case  | V.length pool == 1 = new_fronts --end case: sort the last remaining individual and return the sorted fronts  | otherwise = rankSort new_pool new_fronts  where    new_pool = V.tail pool    start_front = V.fromList [V.fromList [(pool V.! 0){ rank = 0 }]] -- first ind. always has rank 0    upd_ind = rankIndex (V.head pool) fronts    rank' = rank upd_ind    upd_front = V.snoc (fronts V.! rank') upd_ind -- add individual to already existing front    new_fronts = if rank' == V.length fronts      then V.snoc fronts (V.fromList [upd_ind]) -- add a new front with ind as member      else V.update fronts (V.fromList [(rank', upd_front)]) -- add individual to existing front-- Take an individual and find the index of the front where it is not dominated by any members. This index is the rank.rankIndex :: Ind -> Fronts -> IndrankIndex ind fronts  | ind `domByFront` V.last fronts = ind { rank = V.length fronts }  | otherwise = ind { rank = binSearch ind fronts 0 (V.length fronts - 1) }-- Find the index of the front where the individual can be inserted without being dominated-- Note that each individual in fronts[k] dominates at least one member of fronts[k+1].-- Therefore the correct insertion point for an individual is k if-- (ind `domByFront` fronts[k-1][-1]) and not (ind `domByFront` fronts[k][-1])binSearch :: Ind -> Fronts -> Int -> Int -> IntbinSearch ind_a fronts low high  | low == high = low  | ind_b `dominates` ind_a = binSearch ind_a fronts (mid+1) high  | otherwise = binSearch ind_a fronts low mid  where    mid = (low+high) `div` 2    ind_b = V.last (fronts V.! mid)-- Returns true of individual x dominates individual y; false if y dominates x or neither dominate each other-- An individual x dominates an individual y if it is no worse in all objectives and strictly better in at least one.-- For our problem, better means less.dominates :: Ind -> Ind -> Boolind_a `dominates` ind_b = strictly_better && no_worse  where    strictly_better = V.or (V.zipWith (<) x y)    no_worse = V.and (V.zipWith (<=) x y)    x = fitnesses ind_a    y = fitnesses ind_b-- Returns whether or not an individual is dominated by any members of the frontdomByFront :: Ind -> Pool -> Boolind `domByFront` front = V.any dom front  where    dom x = x `dominates` indGenome.hsmodule Genome (  Ind(fitnesses, genome, rank, cdist), Pool, Fronts,  toInd, setRankP, setRankI, setCdistP, setCdistI, getFit) whereimport qualified Data.Vector                  as Vimport           Data.Vector.Algorithms.Intro as VAimport qualified Data.Vector.Mutable          as VMdata Ind = Ind { fitnesses :: V.Vector Float               , genome    :: String               , rank      :: Int               , cdist     :: Float -- Crowding distance               }type Pool = V.Vector Indtype Fronts = V.Vector Poolinstance Show Ind where   show Ind{ fitnesses = f, rank = r } = show f ++ r ++ show rtoInd :: (Float, Float) -> IndtoInd (f1, f2) = Ind (V.fromList [f1, f2])  (-1) (-1)setRankP :: Pool -> Int -> Int -> PoolsetRankP pool idx rank' = V.update pool (V.fromList [(idx, updInd)])  where updInd = (pool V.! idx) { rank = rank' }setRankI :: Ind -> Int -> IndsetRankI ind rank' = ind { rank = rank' }setCdistP :: Pool -> Int -> Float -> PoolsetCdistP pool idx cdist' = V.update pool (V.fromList [(idx, updInd)])  where updInd = (pool V.! idx) { cdist = cdist' }setCdistI :: Ind -> Float -> IndsetCdistI ind cdist' = ind { cdist = cdist' }getFit :: Pool -> Int -> Int -> FloatgetFit pool indIdx fitIdx = fitnesses (pool V.! indIdx) V.! fitIdxSortUtils.hsmodule SortUtils (  indCmpFit, poolSort) whereimport           Control.Monad.STimport qualified Data.Vector                  as Vimport           Data.Vector.Algorithms.Intro as VAimport           GenomepoolSort :: Pool-> (Ind -> Ind -> Ordering) -> PoolpoolSort pool cmp = runST (do    v <- V.unsafeThaw pool    VA.sortBy cmp v    V.unsafeFreeze v)-- Comparator to sort a list of individuals by increasing order of fitIdx-- and for individuals with equal fitIdx, with increasing order of fitIdx+1indCmpFit :: Ind -> Ind -> Int -> OrderingindCmpFit x y fitIdx  | a0 < b0 = LT  | a0 > b0 = GT  -- Can assume (fst x) == (fst y) beneath  | a1 < b1 = LT  | a1 > b1 = GT  | a1 == b1 = EQ  where    f1 = if fitIdx == 0 then 0 else 1    f2 = if fitIdx == 0 then 1 else 0    a0 = fitnesses x V.! f1    a1 = fitnesses x V.! f2    b0 = fitnesses y V.! f1    b1 = fitnesses y V.! f2
Haskell Non-Dominated sorting
haskell;sorting;genetic algorithm