I'm modeling a count up/down timer. After the origin date is set, the timer displays how much time has passed since-, or remains till that origin date.
type OriginDefined
= Up Date
| Down Date
type Origin
= OriginDefined
| OriginUndefined
type Model
= Tick OriginDefined
| Edit Origin
Thus, the timer is ticking only when the origin date is defined. When the origin is edited though, it may or may not be previously defined.
Now I need a function to return the defaultValue
for the date input, when we're in the Edit
mode.
dateInputDefaultValue : Origin -> String
dateInputDefaultValue origin =
case origin of
OriginUndefined ->
""
OriginDefined ->
...
Here I struggle to destructure the origin
further as an Up date
or Down date
. In the 2nd branch of the case
expression the compiler refuses to treat the origin
as anything more specific than just an Origin
.
Here's an Ellie https://ellie-app.com/3zKCcX87wa1/0
How should I deal with a model like that? Should I model in a different way?
Your types compile, but you have two different definitions of OriginDefined
: One is a type called OriginDefined
which has two constructors, Up
and Down
. The other is a parameterless constructor on the type Origin
.
My hunch is that you were trying to get the OriginDefined
constructor on Origin
to carry a value of type OriginDefined
. In order to do that, you would have to define a parameter of type OriginDefined
on the OriginDefined
constructor:
type Origin
= OriginDefined OriginDefined
| OriginUndefined
Now you have a type that is isomorphic to Elm's Maybe
type, so perhaps it would be less confusing and more idiomatic to remove the OriginDefined
type and replace the definition of Origin
with this:
type Origin
= Up Date
| Down Date
Now you can use Maybe
in the places you were previously using defined/undefined nomenclature:
type Model
= Tick (Maybe Origin)
| Edit Origin
Pattern matching on Maybe Origin
could look like this:
dateInputDefaultValue : Maybe Origin -> String
dateInputDefaultValue origin =
case origin of
Nothing ->
""
Just (Up date) ->
"…"
Just (Down date) ->
"…"