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