Lyle Kopnicky
2017-07-24 02:16:01 UTC
I have a series of datatypes that have already been modeled in a relational
database in a product. I'm trying to construct a lighter-weight in-memory
representation in Elm for purposes of simulating operations and visualizing
the results. Ultimately I will probably want to do some export/import
operations that will allow someone to view data from the real database, or
create records in a test database. But, I don't think the in-memory
representations need to correspond exactly to the database ones in order to
do this. I'd like to focus on as simple of a representation as possible,
and I'm leaving out a fair number of fields.
We start with a provided series of AssessmentEvents. It's just a limited
amount of data for each AssessmentEvent. Some of the fields in the database
can be calculated from the others, so those don't need to be provided. From
this data, we can calculate more information about the AssessmentEvents,
including deltas between them. We can also derive a series of Accounts in a
completely deterministic fashion. Each AssessmentEvent will have up to two
years associated with it, and for each year there will be at least one
Account. From this we can also calculate one or two Bills to go with each
Account.
It's a fairly complex calculation. Certainly I can do it in Elm. But what
I'm waffling about is how to store the data. These calculations can be
cached - they do not need to be repeated if the user just changes their
view of the data. They only need to be revised if the user wants to
insert/edit/update AssessmentEvents. So to do all these calculations every
time the user shifts the view would be wasteful.
It becomes tricky with immutable data. In an object-oriented program, I
would probably just have, say, extra empty fields on the AssessmentEvent
object, that I would fill in as I updated the object. E.g., it could have a
list of accounts, which initially would be a null value until I filled it
in.
At first I thought I might do something similar in the Elm data structure.
An AssessmentEvent can contain a List of Accounts (I'm oversimplifying as
it really needs to list the accounts per year). The list of Accounts can be
initially empty. Then as I calculate the accounts, I can create a new list
of AssessmentEvents that have Accounts in the list. But wait - since the
list of AssessmentEvents is immutable, I can't change it. I can only create
a new one, and then, where in the model do I put it?
When a user initializes the model, then, what should they pass in? Perhaps
they can pass in a list of AssessmentEvents that each have an empty list of
Accounts, and then that gets stored in a variable. Then the Accounts are
calculated, and we generate a new list of AssessmentEvents with Accounts
attached, and that is what gets stored in the model.
But this has some shortcomings. The user must now create something that has
this extra unused field on it (and there will be more). I guess if they are
using a function to create it, they needn't know that there are these extra
fields. But what if the field isn't a list - it's an Int? Then do we need
to make it a Maybe Int? Then all the code that later operates on that Int
will have to handle the case that the Maybe Int might be a Nothing, even
though at that point I know it will always be Just something.
Maybe there should be a data structure that contains an AssessmentEvent,
also containing the extra fields? But what if I have a series of functions,
each of which adds some new field to the AssessmentEvent? Then I need a new
data type for each step that just adds one more field?
Perhaps if I use untagged records, then all the functions can just operate
on the fields they care about, ignoring extra fields. I sort of liked the
extra type safety that came with the tagged record, but it may just get in
the way.
Perhaps instead of attaching this extra data to AssessmentEvents, it could
be kept in separate data structures? But then how do I know how they are
connected? Unless I carefully manage the data in parallel arrays, I will
need to add IDs to the AssessmentEvents, so they can be stored in a Dict.
These are just some of my thoughts. Does anyone have any suggested patterns
to follow?
Thanks,
Lyle
database in a product. I'm trying to construct a lighter-weight in-memory
representation in Elm for purposes of simulating operations and visualizing
the results. Ultimately I will probably want to do some export/import
operations that will allow someone to view data from the real database, or
create records in a test database. But, I don't think the in-memory
representations need to correspond exactly to the database ones in order to
do this. I'd like to focus on as simple of a representation as possible,
and I'm leaving out a fair number of fields.
We start with a provided series of AssessmentEvents. It's just a limited
amount of data for each AssessmentEvent. Some of the fields in the database
can be calculated from the others, so those don't need to be provided. From
this data, we can calculate more information about the AssessmentEvents,
including deltas between them. We can also derive a series of Accounts in a
completely deterministic fashion. Each AssessmentEvent will have up to two
years associated with it, and for each year there will be at least one
Account. From this we can also calculate one or two Bills to go with each
Account.
It's a fairly complex calculation. Certainly I can do it in Elm. But what
I'm waffling about is how to store the data. These calculations can be
cached - they do not need to be repeated if the user just changes their
view of the data. They only need to be revised if the user wants to
insert/edit/update AssessmentEvents. So to do all these calculations every
time the user shifts the view would be wasteful.
It becomes tricky with immutable data. In an object-oriented program, I
would probably just have, say, extra empty fields on the AssessmentEvent
object, that I would fill in as I updated the object. E.g., it could have a
list of accounts, which initially would be a null value until I filled it
in.
At first I thought I might do something similar in the Elm data structure.
An AssessmentEvent can contain a List of Accounts (I'm oversimplifying as
it really needs to list the accounts per year). The list of Accounts can be
initially empty. Then as I calculate the accounts, I can create a new list
of AssessmentEvents that have Accounts in the list. But wait - since the
list of AssessmentEvents is immutable, I can't change it. I can only create
a new one, and then, where in the model do I put it?
When a user initializes the model, then, what should they pass in? Perhaps
they can pass in a list of AssessmentEvents that each have an empty list of
Accounts, and then that gets stored in a variable. Then the Accounts are
calculated, and we generate a new list of AssessmentEvents with Accounts
attached, and that is what gets stored in the model.
But this has some shortcomings. The user must now create something that has
this extra unused field on it (and there will be more). I guess if they are
using a function to create it, they needn't know that there are these extra
fields. But what if the field isn't a list - it's an Int? Then do we need
to make it a Maybe Int? Then all the code that later operates on that Int
will have to handle the case that the Maybe Int might be a Nothing, even
though at that point I know it will always be Just something.
Maybe there should be a data structure that contains an AssessmentEvent,
also containing the extra fields? But what if I have a series of functions,
each of which adds some new field to the AssessmentEvent? Then I need a new
data type for each step that just adds one more field?
Perhaps if I use untagged records, then all the functions can just operate
on the fields they care about, ignoring extra fields. I sort of liked the
extra type safety that came with the tagged record, but it may just get in
the way.
Perhaps instead of attaching this extra data to AssessmentEvents, it could
be kept in separate data structures? But then how do I know how they are
connected? Unless I carefully manage the data in parallel arrays, I will
need to add IDs to the AssessmentEvents, so they can be stored in a Dict.
These are just some of my thoughts. Does anyone have any suggested patterns
to follow?
Thanks,
Lyle
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.