A PairDict with no pairs inside
Create a PairDict from a association-Dict. left is the key, right is the value.
If multiple equal keys or values are present, the value first in the Dict is prefered (see putIn).
lowerToUpperLetters=
AssocList.empty
|>AssocList.insert 'a' 'A'
|>AssocList.insert 'b' 'B'
lowerUpperLetters=
PairDict.fromDict
(\k v-> { lowercase= k, uppercase= v })
.lowercase .uppercase
lowerToUpperLettersCreate a PairDict conveniently from pairs.
If right or left values are given multiple times, the value first in the List is prefered (see putIn).
PairDict.fromList
[ { lowercase= 'b', uppercase= 'B' } --put in
, { lowercase= 'a', uppercase= 'A' } --put in
, { lowercase= 'b', uppercase= 'C' }
--ignored, as the left value already exists
, { lowercase= 'c', uppercase= 'A' }
--ignored, as the right value already exists
, { lowercase= 'c', uppercase= 'C' } --put in
]A Json.Decode.Decoder for PairDicts encoded by encodePair.
The order of insertion is not reconstructed (see equal)
type alias NamedNumber=
{ number: Int
, name: String
}
decodeNamedNumber=
Decode.map NamedNumber
(\{ number, name }->
Decode.object
[ ( "number", Decode.int number )
, ( "name", Decode.string name )
]
)
"""
[
{
\"left\": 2,
\"right\": "two"
},
{
\"left\": 1,
\"right\": "one"
}
]
"""
|>Decode.decodeString
(PairDict.decode .number .name
decodeNamedNumber
)
Ok (Pairs [ { number= 1, name= "one" }, { number= 2, name= "two" } ])= aPairDict
using built-in (==) equality is often not useful in the context of association-dicts.
Do these 2 PairDicts have the same size and identical pairs (ignoring insertion order)?
letterCodes=
PairDict.fromList .letter .code
[ { letter= 'a', code= 97 }
, { letter= 'b', code= 98 }
]
fancyCompetingLetterCodes=
PairDict.empty .code .letter
|>PairDict.putIn { code= 98, letter= 'b' }
|>PairDict.putIn { code= 97, letter= 'a' }
PairDict.equal
letterCodes
fancyCompetingLetterCodes
True
Just the pair in which key is present in the PairDict,
if no pair with the key is found Nothing.
casedLetters=
PairDict.empty .lowercase .uppercase
|>PairDict.putIn { lowercase= 'a', uppercase= 'A' }
|>PairDict.putIn { lowercase= 'b', uppercase= 'B' }
lowercase char=
PairDict.access .uppercase char
casedLetters
|>Maybe.map .lowercase
uppercase char=
PairDict.access .lowercase char
casedLetters
|>Maybe.map .uppercaseNote: If accessKey is neither accessLeft or accessRight (see empty, fromList, fromDict),
access will find the most recently inserted value where key is equal in the pair.
PairDict.empty .lowercase .uppercase
|>PairDict.putIn { inAlphabet= 0, lowercase= 'a', uppercase= 'A' }
|>PairDict.putIn { inAlphabet= 1, lowercase= 'b', uppercase= 'B' }
|>PairDict.access .inAlphabet 1
{ inAlphabet= 1, lowercase= 'b', uppercase= 'B' }
ifEmpty if the PairDict contains no pairs,
else ifMore with the most recently putIned pair followed by a PairDict with the other pairs.
It has a very similar use case to a case .. of on a List.
isEmpty=
PairDict.emptyOrMore
{ ifEmpty= True
, ifMore= \_ _-> False
}
mostRecent=
PairDict.emptyOrMore
{ ifMore= \pair _-> Just pair
, ifEmpty= Nothing
}
removeMostRecent pairDict=
pairDict
|>PairDict.emptyOrMore
{ ifMore= \_ rest-> rest
, ifEmpty= pairDict
}How many pairs there are in a PairDict.
PairDict.fromList .number .following
(List.map (\i-> { number= i, following= i+1 })
(List.range 0 41)
)
|>PairDict.size
42
Put in a pair.
If either value is already present, the PairDict is unchanged.
specialCasedA=
{ lowercase= 'a', uppercase= 'A', inAphabet= 0 }
casedBadB=
{ lowercase= 'b', uppercase= 'B', inAlphabet= 0 }
PairDict.empty .lowercase .uppercase --lowercase and uppercase are unique across each pair
|>PairDict.putIn casedBadB --put in
|>PairDict.putIn specialCasedA --put in, because inAlphabet isn't checked
|>PairDict.putIn { lowercase= 'b', uppercase= 'C' }
--ignored, the left value already exists
|>PairDict.putIn { lowercase= 'c', uppercase= 'A' }
--ignored, the right value already exists
|>PairDict.putIn { lowercase= 'c', uppercase= 'C' } --put inCombine 2 PairDicts, so that the pairs in toInsert are put into preferred.
If a value on the left or right is present, prefer the last PairDict (see putIn).
numberNamedOperators=
PairDict.fromList
[ { operator= '+', name= "plus" }
, { operator= '-', name= "minus" }
]
customNamedOperators=
PairDict.fromList
[ { operator= '∧', name= "and" }
, { operator= '∨', name= "or" }
, { operator= '-', name= "negate" }
]
validNamedOperators=
PairDict.union
custumNamedOperators --has a '-' left
numberOperatorNames --preferred → its '-'-pair is put inRemove the left-right pair at left.
If the value does not exist, the PairDict is unchanged
openClosedBrackets=
PairDict.empty .open .closed
|>PairDict.putIn { open= "(", closed= ")" }
openClosedBrackets
|>PairDict.remove .open ")"
--unchanged, ")" is not a open value
|>PairDict.remove .open "("
PairDict.empty
openClosedBrackets
|>PairDict.remove .closed "("
--unchanged, "(" is not a closed value
|>PairDict.remove .closed ")"
PairDict.empty
Notice: If you don't specify accessValue as left or right, it acts as a normal filter
PairDict.empty .open .closed
|>PairDict.putIn { open= "(", closed= ")", meaning= Nothing }
|>PairDict.putIn { open= "[", closed= "]", meaning= Just (List Element) }
|>PairDict.putIn { open= "<, closed= ">", meaning= Nothing }
|>PairDict.remove .meaning NothingValues on the pairs.
brackets=
PairDict.fromList .open .closed
[ { open= '(', closed= ')' }
, { open= '{', closed= '}' }
]
open= values .open brackets
closed= values .closed bracketsReduce the left-right pairs from most recently putIned to least recently putIned.
A fold in the other direction doesn't exist, as association-Dicts should rarely rely on order (see equal).
brackets=
PairDict.empty
|>PairDict.putIn ( '(', ')' )
|>PairDict.putIn ( '{', '}' )
openingAndClosing=
brackets
|>PairDict.fold
(\( left, right ) acc->
acc++[ String.fromList [ left, right ] ]
)
[]
[ "{}", "()" ]
Map pairs. Take a look at pair's map operations.
digitNames=
PairDict.empty .number .name
|>PairDict.putIn { number= 0, name= "zero" }
|>PairDict.putIn { number= 1, name= "one" }
mathSymbolNames=
digitNames
|>PairDict.map .symbol .name
(\{ number, name }->
{ symbol= String.fromInt number, name= name }
)
|>PairDict.putIn { symbol= "+", name= "plus" }Convert a PairDict to an association-Dict, which you can access only from the left.
casedLetters=
PairDict.fromList .lowercase .uppercase
[ { uppercase= 'A', lowercase= 'a' }
, { uppercase= 'B', lowercase= 'b' }
]
lowerFromUpper=
PairDict.toDict casedLettersConvert a PairDict to a Json.Encode.Value.
somePairDict=
PairDict.empty
|>PairDict.putIn ( 1, 11 )
|>PairDict.putIn ( 2, 22 )
Encode.encode 1
(PairDict.encode
Encode.int Encode.int
somePairDict
)
"""
[
{
\"left\": 2,
\"right\": 22
},
{
\"left\": 1,
\"right\": 11
}
]
"""
Want to look up value-pairs from the left or the right?
Like assoc-list, a
PairDictallows for anything as values except for functions and things that contain functions.Example: cased letters