Skip to content

Instantly share code, notes, and snippets.

@el-hult
Last active November 6, 2023 10:43
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 el-hult/197020edb6e860917f70a736bb35f53f to your computer and use it in GitHub Desktop.
Save el-hult/197020edb6e860917f70a736bb35f53f to your computer and use it in GitHub Desktop.
Two bad implementations of a Set in haskell
{- A module implementing a simple (and quite dumb) set -}
module MySet1 (Set, empty, toList, insert, contains) where
import Data.List(nub)
{- Set
A set, backed by a regular list.
If the list has duplicates, it is nothing the user should notice
-}
data Set a = SetC [a]
{- an empty set -}
empty :: Set a
empty = SetC []
{- insert s e
Insert element e into set s
This function maintains all type invariants (since there are none) -}
insert :: Set a -> a -> Set a
insert (SetC xs) e = SetC (e:xs)
{- contains set element
Check if @set@ contains @element@
-}
contains :: Eq a => Set a -> a -> Bool
(SetC xs) `contains` x = x `elem` xs
{- toList set
Convert @set@ to a list, with one element per unique value in @set@
Time complexity is quadratic in length of the set
-}
toList :: Eq a => Set a -> [a]
toList  (SetC xs) = nub xs
{- Another module implementing a simple (and only slightly less dumb) set -}
module MySet2 (Set, empty, toList, insert, contains) where
{- Set
A set, backed by a regular list
INVARIANT: never contains duplicates
-}
data Set a = SetC [a]
{- an empty set -}
empty :: Set a
empty = SetC []
{- insert set element
Insert @element@ into @set@
Time complexity depends on the @contains@ function, which is linear.
This function maintains all type invariants by checking the input at every call.
-}
insert :: Eq a => Set a -> a -> Set a
insert s@(SetC xs) e
| s `contains` e = s
| otherwise = SetC (e:xs)
{- contains set element
Check if @set@ contains @element@
Time complexity is linear in length of the set
-}
contains :: Eq a => Set a -> a -> Bool
(SetC xs) `contains` x = x `elem` xs
{- toList set
Convert @set@ to a list, with one element per unique value in @set@
Time complexity is constant
Optimization enabled by the invariant on @set@
-}
toList :: Eq a => Set a -> [a]
toList  (SetC xs) = xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment