I saw some chatter in slack the other day about two ways of representing a list that is guaranteed to never be empty. One way is to use a module that encapsulates this invariant, such as non-empty-list. Another way is to use a tuple (a, List a)
where the first element is the head and the second element in the tuple is the remainder of this list (which could be an empty list)
It just so happens I have a package published where I was using non-empty-list
and I changed the underlying implementation to now use a tuple…
Pros:
- One less dependency and import statement
- Once the list is reconstructed we can use elm-lang/core’s List functionality
- Removed custom non-empty helper function
Cons:
- Reconstructing the list from head / tail is a bit annoying
- Argument deconstruction + “as” syntax is less readable to me (lines 148 and 198 in Genetic.elm)
- I speculate that
(a, List a)
isn’t beginner friendly
I’m conflicted on the tradeoffs here. Depending on the context and team any of those three cons can be further emphasized.
I’m curious if someone can demonstrate in code or has past experiences with larger codebases / teams to help determine if the balance tips one way or the other.