Multiple key Ordering
s
Configure what's considered a key inside a KeysSet
Create starting with Keys.for
and building with |> Keys.by
as shown in
the readme examples
You can just ignore the Typed
thing but if you're curious → typed-value
oneBy : Mapping element toKeyTag key -> Ordering key keyOrderTag -> Keys element (Key element (Order.By toKeyTag keyOrderTag) key N1) N1
Create Keys
for single key
in case you don't plan on adding more keys.
See also Keys.identity
if you want to use the complete element as the key.
FYI, this is equivalent to
Keys.for identity
|> Keys.by ( identity, mapping ) ordering
identity : Ordering element elementOrderTag -> IdentityKeys element elementOrderTag
Ordering by the element itself.
Short for
Keys.identity order =
Keys.for identity |> Keys.by ( identity, Map.identity ) order
in KeysSet
import Map
import Order
import Int.Order
import Keys
import KeysSet
intUp : IdentityKeys Int Int.Order.Up
intUp =
Keys.identity Int.Order.up
KeysSet.fromList intUp [ -1, 5, 5, 8, 7 ]
--: Emptiable (IdentitySet Int Int.Order.Up) Possibly
|> KeysSet.toList intUp
--> [ -1, 5, 7, 8 ]
Keys element (Key element (Order.By Map.Identity elementOrderTag) element N1) N1
Resulting type of Keys.identity
.
import Map
import Order
import Float.Order
import KeysSet exposing (IdentitySet)
import Keys
floatUp : IdentityKeys Float Float.Order.Up
floatUp =
Keys.identity Float.Order.up
KeysSet.fromList floatUp [ -1.1, 5, 5, 8.7, 7.8 ]
--: Emptiable (IdentitySet Float Float.Order.Up) Possibly
|> KeysSet.toList floatUp
--> [ -1.1, 5, 7.8, 8.7 ]
for : keysConstructor -> KeysBeingBuilt element_ completeKeys_ keysConstructor (N.Up0 keyCount_)
Start a keys builder by giving names to the individual keys as arguments using a record
userKeys :
Keys
User
{ name : Key User (Order.By User.Name Username.Order) Username N2
, email : Key User (Order.By User.Email Email.Order) Email N2
}
N2
userKeys =
Keys.for (\email name -> { email = email, name = name })
|> Keys.by ( .email, User.email, Email.order )
|> Keys.by ( .name, User.name, Username.order )
Emptiable.empty
|> KeysSet.insertIfNoCollision userKeys
{ name = Username "ben", email = "ben10@gmx.de" }
|> KeysSet.insertIfNoCollision userKeys
{ name = Username "mai", email = "ben10@gmx.de" }
-- not inserted
-- There's already an element where .email is "ben10@gmx.de"
|> KeysSet.insertIfNoCollision userKeys
{ name = Username "ben", email = "ben11@gmx.de" }
-- not inserted
-- There's already an element where .name is "ben"
KeysBeingBuiltWithFocus element keysComplete keysConstructor keysConstructor keyCount
Once you supply all the necessary key-Ordering
s with by
,
a KeysBeingBuilt
is automatically of type Keys
.
So if you for example infer the type
KeysBeingBuilt element { yourKeys } { yourKeys } keyCount
you can replace it by
Keys element { yourKeys } keyCount
It's data is unaccessible because you shouldn't be able to
by : ( keysComplete -> Key element (Order.By toKeyTag keyOrderTag) key (N.Add1 keyCountFrom1), Mapping element toKeyTag key ) -> Ordering key keyOrderTag -> KeysBeingBuilt element keysComplete (Key element (Order.By toKeyTag keyOrderTag) key (N.Add1 keyCountFrom1) -> keysConstructedPartially) (N.Up (N.Add1 toKeyCountFrom1) N.To (N.Add1 keyCountFrom1)) -> KeysBeingBuilt element keysComplete keysConstructedPartially (N.Up toKeyCountFrom1 N.To (N.Add1 keyCountFrom1))
Add a key
Keys.for
)Mapping
Ordering
KeysWithFocus element keys keys keyCount
The type of fully constructed KeysBeingBuilt
ready to use.
"infer types" is your friend here
import Keys exposing (Keys, Key)
import Order
import Char.Order
import String.Order
import Emptiable
import N exposing (N2)
userKeys :
-- just infer this
Keys
User
{ name :
Key
User
(Order.By
User.Name
(String.Order.Earlier (Char.Order.AToZ Order.Tie))
)
String
N2
, email : Key User (Order.By User.Email Email.DefaultOrder) String N2
}
N2
userKeys =
Keys.for (\name email -> { name = name, email = email } )
|> Keys.by ( .name, User.name )
(String.Order.earlier (Char.Order.aToZ Order.tie))
|> Keys.by ( .email, User.email )
Email.defaultOrder
Emptiable.empty
|> KeysSet.insertIfNoCollision userKeys
{ username = "ben", email = ..ben10@gmx.de.. }
|> KeysSet.insertIfNoCollision userKeys
{ username = "mai", email = ..ben10@gmx.de.. }
-- not inserted
-- There's already an element where .email is ..ben10@gmx.de..
What's with those Up N.. To N..
?
Internally, each key will be assigned an index.
that type from bounded-nat
preserves the knowledge that each key's index is less than the whole count.
KeysBeingBuiltWithFocus element keys keys focus (N.On keyCount)
You'll find this type on operations like KeysSet.remove
which require you to specify which specific key from the pool of keys elements will be removed by.
If you just have one key, like from oneBy
or identity
,
just supply the keys and everything will work.
If you have multiple keys, use key
to "select" one.
key : (keys -> focusNew) -> KeysWithFocus element keys focusOld_ keyCount -> KeysWithFocus element keys focusNew keyCount
You might need this on operations like KeysSet.remove
which require you to specify which specific key from the pool of keys elements will be removed by.
If you just have one key, like from oneBy
or identity
,
just supply the keys and everything will work.
If you have multiple keys, use key
to "select" one, like
userKeys =
Keys.for (\name email -> { name = name, email = email } )
|> Keys.by ( .name, User.name )
(String.Order.earlier (Char.Order.aToZ Order.tie))
|> Keys.by ( .email, User.email )
Email.defaultOrder
users
|> KeysSet.remove (key .name userKeys) "default"
You won't need them if you just want to use KeysSet
.
... It's safe to expose this information, tho, so why not make it available :)
Internal.Key element orderByTag key keyCount
By which aspect = key and in which key Order
elements should be sorted
toArray : KeysWithFocus element keys_ focus_ keyCount -> ArraySized (( element, element ) -> Basics.Order) (N.Exactly (N.On keyCount))
List all keys in the keys
record as an array
of functions
determining the Order
of 2 elements
toKeyWith : KeysWithFocus element keys_ (Key element orderByTag_ key keyCount) keyCount -> element -> key
How to turn the element into the specified key
keyOrderWith : KeysWithFocus element keys_ (Key element orderByTag_ key keyCount) keyCount -> ( key, key ) -> Basics.Order
How to order by the specified key