A replacement for elm/core
's Set
data structure; the difference is that
members can be of any type, not just comparable
.
(When I say "any" type, there's one proviso: you must be able to provide a pair
of functions that can convert your member type into a comparable
and back
again. So this won't work with functions, but it will work with custom types.)
{ empty : Set a comparable
, singleton : a -> Set a comparable
, insert : a -> Set a comparable -> Set a comparable
, remove : a -> Set a comparable -> Set a comparable
, isEmpty : Set a comparable -> Basics.Bool
, member : a -> Set a comparable -> Basics.Bool
, size : Set a comparable -> Basics.Int
, union : Set a comparable -> Set a comparable -> Set a comparable
, intersect : Set a comparable -> Set a comparable -> Set a comparable
, diff : Set a comparable -> Set a comparable -> Set a comparable
, toList : Set a comparable -> List a
, fromList : List a -> Set a comparable
, map : (b -> comparable2) -> (a -> b) -> Set a comparable -> Set b comparable2
, foldl : (a -> output -> output) -> output -> Set a comparable -> output
, foldr : (a -> output -> output) -> output -> Set a comparable -> output
, filter : (a -> Basics.Bool) -> Set a comparable -> Set a comparable
, partition : (a -> Basics.Bool) -> Set a comparable -> ( Set a comparable
, Set a comparable )
, toggle : a -> Set a comparable -> Set a comparable
}
An Interface
is just a record containing functions that mirror the API of
the elm/core
Set
module.
The type signature might look daunting, but in practice you can ignore it.
All you need to remember is that if you create an Interface
called set
, you
can use it just like the elm-core
Set
API:
-- elm/core
mySet =
Set.singleton 1
-- edkelly303/elm-any-type-collections
set =
Any.Set.makeInterface
{ fromComparable = identity
, toComparable = identity
}
mySet =
set.singleton 1
map
There is one function in this package's Set
interface that doesn't quite match
the elm-core
Set
API.
The map
function takes an extra argument:
-- elm/core
Set.map :
(comparable -> comparable2)
-> Set comparable
-> Set comparable2
-- edkelly303/elm-any-type-collections
set.map :
(b -> comparable2)
(a -> b)
-> Set a comparable
-> Set b comparable2
This is necessary because map
is able to change the type of the members of the
Set
from a
to b
. We need to provide a way to turn that b
into another
comparable
type so that the resulting Set
will be able to store it.
makeInterface : { toComparable : a -> comparable, fromComparable : comparable -> a } -> Interface a b output comparable comparable2
Use makeInterface
to define an Interface
for your custom Set
type. You need to supply two functions:
toComparable
, which converts your key type into any comparable
type (i.e.
Int
, String
, Float
, or a tuple containing only comparable
types)fromComparable
, which converts that same comparable
type back into your
key type.It's a good idea to define the Interface
as a top-level value. Once you've
defined the Interface
, you can use it anywhere in your code without needing to
pass it explicitly to your functions.
For example, here we define the Interface
as a top-level value called idSet
:
type Id
= Id Int
idSet =
makeInterface
{ toComparable = \(Id int) = int
, fromComparable = Id
}
myIdSet =
idSet.fromList [ Id 1, Id 2, Id 3 ]
thisIsTrue : Bool
thisIsTrue =
idSet.member (Id 2) myIdSet