I am trying to program small time tracking application, where I write what I do, and it just logs it.
I successfully implemented adding entries to log, but now, I want to update last log entry with duration (for example when I started programming at 00:01, now it is 00:20 and I starting to write question on SO, so when I add that log entry to list, I want head of the list to have duration of 19 minutes, so I know how much time I spent programming).
I try to do it with this code:
addEntry: Model -> List LogEntry
addEntry model =
let
newEntry = { -- this is what we add
text = model.currentText,
timestamp = model.now,
duration = Nothing
}
lastEntry =
List.head model.log
in
case lastEntry of
Nothing ->
[newEntry] -- when the list was empty - create it with one element
Just le -> -- when not empty
newEntry :: {le | duration = newEntry.timestamp - le.timestamp } :: List.tail model.log
-- - add new element, modified head and tail
The problem is that List.tail model.log
is Maybe List LogEntry
, and I want it to be Just List LogEntry
. And it could only be Just List LogEntry
there, because head is also Just LogEntry
.
What to do there? Nest another one case
and mark one branch as unaccessible? Is there some pattern how to do this? Or function like List a -> Maybe (a, List a)
, that returns head and tail in the same Maybe
?
Use pattern matching on lists (a list may be the empty list or a cons of head and tail):
let newEntry = {
text = model.currentText,
timestamp = model.now,
duration = Nothing
}
in case model.log of
[] -> [newEntry]
le :: log ->
let le' = { le | duration = newEntry.timestamp - le.timestamp }
in newEntry :: le' :: log