This is cool but more and more I wish functional languages would have a standard library trait/typeclass called something like FromLiteral, with the signature FromLiteral a => String -> Result a.
FromLiteral a => String -> Result a
Then, if you had a string literal in your code but the compiler infers it should be a Regex, it calls the FromLiteral implementation for Regex at compile time, and either rewrites the generated program with the successful output, or throws an error.
Bit irritating how Elm forces you to go into an infinite loop (fromLiteral string = fromLiteral string) instead of letting you crash with a nice error in the impossible case with the old Debug.crash. (That’s Debug.todo since Elm 0.19, and is only permitted if you compile in debug mode.)
fromLiteral string = fromLiteral string
I suppose one might define and use
impossible : a -> a
impossible x = impossible x
in those spots as a means of documentation.
Somewhat relatedly, I find Elm’s insistance on not allowing “unsafe” operations to lead to obfuscation of failure cases. E.g., it’s common to have a catch-all case in your update function that just silently discards unexpected message combinations:
update : Msg -> Model -> Model
update msg model = case (msg, model.state) of
-- handle expected combinations
-- ignore impossible combinations
_ -> model
-- instead of the more helpful
-- Debug.crash <| "unexpected message/state combination: "
++ Debug.toString msg ++ ", " ++ Debug.toString model.state
You don’t have to discard invalid states in the catch-all clause silently though. You could still send them to an error-reporting service, for example (although not in the specific case you show - you’d have to use something other than Browser.sandbox).
I wonder how this contrasts with later-binding techniques like E-style auditors. Both systems walk an AST and examine whether an expression fulfills a contract; elm-review certifies modules, while E-style auditors certify objects.
It seems that the biggest difference is that elm-review is optional; it is possible to forget to run the tool. In contrast, E-style auditors are not skippable, but must be executed at runtime. The other big difference is that elm-review is policy chosen unilaterally by the code reviewer and applied evenly over the entire source tree, while E-style auditors are chosen by contract with consenting objects and only applied at each annotated object construction site.