Hello,
I just finished programming a little function in Elm.
You have nested dictionaries representing dates. A first level in the dictionary is for years, second level for months, third level for days, and then in each day dictionnary, you have names (strings) with counts.
Like so:
{
2021: {
8: {
31: {"Jeremy": 1}
},
9: {
7: {"Jane": 5},
10: {"Sandra": 5},
12: {"Michel": 2, "Pedro": 2}
}
}
}
I wrote a function to increase a count associated to one of the names in the dictionary.
Here’s the function written in Elm:
module Achievements exposing (Achievements)
import Dict exposing (Dict)
type alias Achievements =
Dict Int (Dict Int (Dict Int (Dict String Int)))
increaseCount : Int -> Int -> Int -> Int -> String -> Achievements -> Achievements
increaseCount increment year month day name achievements =
case Dict.get year achievements of
Nothing ->
Dict.insert
year
(Dict.fromList
[ ( month
, Dict.fromList
[ ( day
, Dict.fromList
[ ( name, increment ) ]
)
]
)
]
)
achievements
Just yearData ->
case Dict.get month yearData of
Nothing ->
Dict.insert
year
(Dict.insert
month
(Dict.fromList
[ ( day
, Dict.fromList
[ ( name, increment ) ]
)
]
)
yearData
)
achievements
Just monthData ->
case Dict.get day monthData of
Nothing ->
Dict.insert
year
(Dict.insert
month
(Dict.insert
day
(Dict.fromList
[ ( name, increment ) ]
)
monthData
)
yearData
)
achievements
Just dayData ->
case Dict.get name dayData of
Nothing ->
Dict.insert
year
(Dict.insert
month
(Dict.insert
day
(Dict.insert
name
increment
dayData
)
monthData
)
yearData
)
achievements
Just n ->
Dict.insert
year
(Dict.insert
month
(Dict.insert
day
(Dict.insert
name
(n + increment)
dayData
)
monthData
)
yearData
)
achievements
That’s 101 lines of code.
In Python I would obtain the same functionality with those 11 lines:
class Achievements:
def __init__(self):
self._dct = {}
def increase_count(self, increment, year, month, day, name):
self._dct \
.setdefault(year, {}) \
.setdefault(month, {}) \
.setdefault(day, {}) \
.setdefault(name, 0)
self._dct[year][month][day][name] += increment
I realize the Python version doesn’t come with type safety and so an Elm version would necessarily be longer just to deal with the types. It’s also not stateless, which could be an inconvenient in some cases. But how can I make the Elm version terser and more readable?