Indexed Dictionaries
A Dict data structure that derives keys from values. It provides a safe and lazy way to work with indexed data structures and wraps around elm/core/Dict.
Use singleton
, empty
or fromListBy
to create and IxDict using a key function:
type alias User =
{ id : String
, name : String
}
users : IxDict.IxDict comparable User
users =
IxDict.fromListBy .id
[ User "alice" "Alice"
, User "bob" "Bob"
]
Use the IxDict
lib to build, query, list, transform and combine IxDict
s. For example:
updated : IxDict.IxDict comparable User
updated =
users
|> IxDict.insert (User "charlie" "Charlie")
|> IxDict.remove "bob"
And that's it!
Note that you can use not just records, but any data type that can be converted to a comparable
via the keyFn
. This also applies to keys. For example:
tuples : Maybe ( number, String )
tuples =
IxDict.empty Tuple.first
|> IxDict.insert ( 2, "Twice the fun" )
|> IxDict.insert ( 3, "Three" )
|> IxDict.get 3
You also get sets out of the box. (Although you might want to use the core/Set library, which actually uses Dict s ()
under the hood!)
set =
IxDict.empty identity
setOfStrings =
IxDict.singleton identity "0I8V-QZFNC3LHhQavdQmz"
setOfNumbers =
IxDict.singleton identity 8985373
setOfTuples =
IxDict.singleton identity ( 100, 200 )
Given a conventional Dict
of type Dict String User
,
usersOld : Dict String User
usersOld =
Dict.empty
-- | Wrong key
|> Dict.insert "charlie" (User "alice" "Alice")
-- | Inconvenient
|> Dict.insert bob.id bob -- bob = User "bob" "Bob"
two problems arise from this approach:
- We have no guarantee that the
Dict
keys map to the same.id
field in users. - Having to deal with accessing .id everythime we want to do a
Dict
operation is just inconvenient. This also applies to other Data structures used as values, i.e. Tuples
Having encountered the same problem in PureScript, Michael inspired me to generalize it into a small library. Check out his purescript-ix-maps
Using the IxDict data constructor alone is unsafe when doing operations, since it is not guaranteed that the keyFn is applied. It is not exported and you have to use empty
, singleton
, fromListBy
or fromDictBy
to construct your IxDict.
Also, the map fn is not a valid Functor as it is not structure-preserving. An example case: mapping const x over an ixDict with n > 1 elements will result in a set with one element.