I recently saw a discussion on slack about the type annotations for functions that can return any type. For example:
myList : List a or
myMaybe : Maybe a
myList must be an empty list because how else could it be a list containing any type of value.
myMaybe must be
Nothing because if it was
Just "hello" or
Just anything it would not be able to have the type
Now it has taken me ~6 months of using with elm to realise the truth of the above two statements despite how obvious they seem to me now I have clocked them. For a long time, I thought that ports are defined with a generic return type because they were in some way “magic”. Instead, commands related to a port will never give a message back to the update function.
The realisation came when I was trying out rust and found https://doc.rust-lang.org/nightly/book/second-edition/ch19-04-advanced-types.html#the-never-type-that-never-returns. In rust there is a special symbol for this “never type” which is
If elm used
! for these never types and I had found a port definition like
port myPort : String -> Cmd ! I may have been very confused. However, I then would have googled “exclamation mark elm” and been taken to the elm docs (or stack overflow) where I would have understood that
! means that no messages can be produced. My confusion would have lasted ~5 minutes instead of ~6 months.
Note: the “never type” in rust is very different from the elm
Never type. The special symbol I am proposing would work exactly like generic return types do currently. For example
empty : List a ->
empty : List ! and the value could be used in exactly the same way as it is now.
I am not necessarily advocating using
! here, other symbols such as
_ would also be viable. Something completely different may also be good.
list1 : a -> List a and
list2 : a -> List b look very similar but are infact have completely different implications. It would be good if they also looked very different.
Edit: added note about elm’s