For a Todo List App, I have come up with a custom data type for collections of tasks. Because I want to edit specific tasks inside a collection, each task gets an ID.
However, the IDs are only unique inside a collection, so I need to keep track of where the task came from. For this I’m using phantom types.
-- Tag for the "done" collection
type Done = Done
-- Empty collection for "done" tasks
tasks = empty Done
updatedTasks = addTask "Buy milk" tasks
Now imagine I render the tasks in the list by mapping the collection (which was converted toList
) to Html Msg
. I then can add a message for editing each item using its ID.
renderSingleTask task =
div [] [ text (getAction task)
, button [onClick <| getId task] [ text "Edit" ]
]
Right now, I am only allowing editing of one list, so my message type looks like this:
Edit (TaskId Done) String
This means that it only accepts IDs from the Done
list. Everything else throws a compiler error. I keep track of the currently edited item in my model using a field editing : Maybe (TaskId Done, String)
.
Now I want to allow edits to all lists. But since I need to keep track of which item I’m currently editing, this entails also keeping track of the list the item is coming from (one can consider this as being part of its ID). So having two lists, one for current, the other for done tasks, I have two types:
type Current = Current
type Done = Done
But I see no way of specifying the editing
field in my model to allow either one. I would like something like:
editing : Maybe (TaskId (Current | Done), String)
Of course that’s a syntactical error. I’ve read a bit about Haskell and I think this is a use case for kinds. But I’m not entirely certain and kinds don’t exist in Elm (as they shouldn’t). This leaves me wondering how to work around the issue.
I am beginning to think that I modeled the collections wrong. So if you know how to solve the issue, even if it means modifying the way my collections work, then please tell me!