Skip to content

Instantly share code, notes, and snippets.

@pkamenarsky
Created December 6, 2020 15:13
Show Gist options
  • Save pkamenarsky/cb45f8da84bddbf8d33437d841dabd45 to your computer and use it in GitHub Desktop.
Save pkamenarsky/cb45f8da84bddbf8d33437d841dabd45 to your computer and use it in GitHub Desktop.
module Data.Set.NonTransitive where
-- | A class for non-transitive equalities, e.g. x == y and y == z doesn't imply x == z.
class NonTransEq a where
nonTransEq :: a -> a -> Bool
newtype Set a = Set { toList :: [a] }
deriving Show
instance (NonTransEq a, Semigroup a) => Semigroup (Set a) where
as <> Set bs = foldr insert as bs
instance (NonTransEq a, Semigroup a) => Monoid (Set a) where
mempty = Set []
fromList :: NonTransEq a => Semigroup a => [a] -> Set a fromList = foldr insert (Set []) fromListWith :: Semigroup a => (a -> a -> Bool) -> [a] -> Set a fromListWith f = foldr (insertWith f) (Set []) insertWith :: Semigroup a => (a -> a -> Bool) -> a -> Set a -> Set a insertWith eq x (Set (a:as)) | x `eq` a = insertWith eq (x <> a) (Set as) | otherwise = Set (a:toList (insertWith eq x (Set as))) insertWith _ x (Set []) = Set [x]
insert :: Semigroup a => NonTransEq a => a -> Set a -> Set a
insert = insertWith nonTransEq
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment