I have an opaque type Nineagram.NineagramPuzzle
, and to get one of these values I have to call Nineagram.fromString
, and the string has some conditions, so it returns a Result Nineagram.CreationProblem NineagramPuzzle
.
In my Main.elm view if the user hasn’t entered a puzzle to solve yet (model.puzzle == Nothing
), I want to just render the usual puzzle view with some default puzzle serving as a placeholder, and so I really just wanted a NineagramPuzzle
literal in Main.elm
for that purpose, but of course I can’t construct that value from opaque type.
The solution I came up with was a pattern where I construct the literals on init and then return a model representing a failure if the literals are not valid, otherwise it returns a model that has the desired inital state plus the literals. Then I updated view to either show an error on the failure state, or call a separate view which accepts the valid literals as an additional argument: viewState : Constants -> State -> Html Msg
Here’s the diff for my app: https://github.com/bukkfrig/nineagram-solver/commit/eae9d2da58630991b1248549363acd367b54c699
If I had tests set up, I could just add a test that init ()
produces the good model and not the bad one to validate my literals.
This is probably overengineering for this simple program, but is this approach sensible for larger programs that need literals that can’t be simply type checked? Have you used a similar approach before?