Skip to content

Instantly share code, notes, and snippets.

@GeoffChurch
Created March 30, 2021 18:44
Show Gist options
  • Save GeoffChurch/3f5dc6cebcdf2ed7772df3b435faae28 to your computer and use it in GitHub Desktop.
Save GeoffChurch/3f5dc6cebcdf2ed7772df3b435faae28 to your computer and use it in GitHub Desktop.
Lazy subsets, product, and binary relations between potentially infinite lists
-- Lazy subsets of potentially infinite list (from https://stackoverflow.com/a/36101787).
subsets :: [a] -> [[a]]
subsets l = [] : go [[]] l
where
go _ [] = []
go seen (cur : rest) = let next = (cur :) <$> seen in next ++ go (seen ++ next) rest
-- Lazy product of potentially infinite lists.
product :: [a] -> [b] -> [(a, b)]
product l r = go1 ([], l) ([], r)
where
go1 (lseen, []) (_, rrest) = [(l, r) | r <- rrest, l <- lseen]
go1 (lseen, lcur : lrest) (rseen, rrest) = ((lcur,) <$> rseen) ++ go2 (lcur : lseen, lrest) (rseen, rrest)
go2 (_, lrest) (rseen, []) = [(l, r) | l <- lrest, r <- rseen]
go2 (lseen, lrest) (rseen, rcur : rrest) = ((,rcur) <$> lseen) ++ go1 (lseen, lrest) (rcur : rseen, rrest)
-- Lazy set of all binary relations between potentially infinite lists.
binRels :: [a] -> [b] -> [[(a, b)]]
binRels l r = subsets (product l r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment