Last active
November 6, 2023 10:43
-
-
Save el-hult/197020edb6e860917f70a736bb35f53f to your computer and use it in GitHub Desktop.
Two bad implementations of a Set in haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- 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