method resolution order
import Data.Function
import Data.Maybe
import Data.List
data Class = Class
{ name :: String
, parents :: [Class]
}
linearize :: Class -> [Class]
linearize c = c : unfoldr search (linearize <$> parents c) where
-- `search lss`, where `lss` is a list of nonempty lists of classes (the
-- remaining classes from the linearization of each superclass), finds the
-- next class in the linearization and removes it from each list that it
-- occurs in. If this leaves any lists empty, it removes them. Returns
-- `Nothing` when there are no classes left.
search [] = Nothing
search lss =
-- The candidate set is given by the heads of the remaining lists.
let hds = head <$> lss
tls = tail <$> lss
-- Find a class that does not occur in any of the remaining lists,
-- except possibly at the beginning.
cls = find (\hd -> all (\tl -> hd `notElem` tl) tls) hds
in case cls of
Nothing -> error "not linearizable"
Just c' ->
Just (c', [ls' | ls <- lss, let ls' = delete c' ls, not (null ls')])
Author: Nicholas Coltharp
Created: 2025-12-04 Thu 00:00
Validate