Skip to content

Instantly share code, notes, and snippets.

@edsko
Created August 14, 2017 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edsko/b6458de07fa4ef9ce08f71b54d78ea9a to your computer and use it in GitHub Desktop.
Save edsko/b6458de07fa4ef9ce08f71b54d78ea9a to your computer and use it in GitHub Desktop.
{-------------------------------------------------------------------------------
Lazy n-ary cartesian product
Most of these functions (except for 'cart' itself) are taken from
"Generics.Deriving.Enum", which in turn are taken from Mark Jones' talk
at AFP 2008.
-------------------------------------------------------------------------------}
-- | n-ary lazy cartesian product
ncart :: HList [] as -> [HList Identity as]
ncart HL.Nil = [HL.Nil]
ncart (xs HL.:& xss) = diag [ [ Identity hd HL.:& tl
| tl <- ncart xss
]
| hd <- xs
]
-- | Diagonalization of nested lists. Ensure that some elements from every
-- sublist will be included. Handles infinite sublists.
diag :: [[a]] -> [a]
diag = concat . foldr skew [] . map (map (\x -> [x]))
skew :: [[a]] -> [[a]] -> [[a]]
skew [] ys = ys
skew (x:xs) ys = x : combine (++) xs ys
combine :: (a -> a -> a) -> [a] -> [a] -> [a]
combine _ xs [] = xs
combine _ [] ys = ys
combine f (x:xs) (y:ys) = f x y : combine f xs ys
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment