module DataStructures.Levels where
import Control.Applicative
Levels
is not recursive data type, but it is important to implement breadth-first search. Implementations in here reference to [Kidne and Wu 2021][^1]. Note that Levels
doesn’t follow the Applicative and Monad law, since below implementation using list for inner groups.
newtype Levels a = Levels [[a]]
deriving (Show, Eq)
choices :: Alternative f => (a -> f b) -> [a] -> f b
choices f [] = empty
choices f (x:xs) = f x <|> choices f xs
wrap :: Levels a -> Levels a
wrap (Levels xs) = Levels ([] : xs)
zipL :: [[a]] -> [[a]] -> [[a]]
zipL [] yss = yss
zipL xss [] = xss
zipL (xs:xss) (ys:yss) = (xs ++ ys) : zipL xss yss
instance Functor Levels where
fmap f (Levels xss) = Levels (map (map f) xss)
instance Foldable Levels where
foldMap f (Levels xss) = mconcat $ map (mconcat . map f) xss
instance Applicative Levels where
pure x = Levels [[x]]
(Levels []) <*> _ = Levels []
(Levels (fs:fss)) <*> (Levels xss) = Levels (map (fs <*>) xss) <|> wrap (Levels fss <*> Levels xss)
instance Alternative Levels where
empty = Levels []
(Levels xss) <|> (Levels yss) = Levels (zipL xss yss)
instance Monad Levels where
(Levels []) >>= k = empty
(Levels (xs:xss)) >>= k = choices k xs <|> wrap (Levels xss >>= k)
[1] Donnacha Oisín Kidney and Nicolas Wu. 2021. Algebras for weighted search. Proc. ACM Program. Lang. 5, ICFP, Article 72 (August 2021), 30 pages. DOI:https://doi.org/10.1145/3473577