In Elm, type
s are not treated as namespaces i.e. you cannot reference it’s members by the TypeName.Member
syntax which is extremely common in other languages. A more complete example:
type MyType =
Variant1
| Variant2
doSomething : MyType -> Int
doSomething thing =
case thing of
MyType.Variant1 -> 1 -- Compiler complains that it can't find #MyType.Variant1#
MyType.Variant1 -> 2 -- ditto
Basically, this became a problem for me when I was mapping between two data structures and I wound up with two modules that had types with members of the same name. Okay, how do I disambiguate these names? The obvious syntax from most other languages didn’t work. This got me stuck against a wall for about an hour and searching in vain for answers to this problem. Even more frustrating, no one seems to have encountered it before. Or they have but figured it out as I later did and it’s never occurred to anyone this can be a real bummer if you’re new to Elm. Example code:
In Module1:
type WhichEntity =
Entity1
| Entity2
In Module2:
import Module1 exposing (WhichEntity(..))
type SelectedEntity =
Entity1
| Entity2
fromRequestMsg : WhichEntity -> SelectedEntity
-- This implementation doesn't work
-- Compiler complains that we're matching WhichEntity against variants of SelectedEntity
fromRequestMsg whichEntity =
case whichEntity of
Entity1 -> Entity1
Entity2 -> Entity2
-- This implementation doesn't work either
-- Compiler complains that it can't find the names #WhichEntity.Entity1# and #WhichEntity.Entity2#
fromRequestMsg whichEntity =
case whichEntity of
WhichEntity.Entity1 -> Entity1
WhichEntity.Entity2 -> Entity2
Now I do understand how to disambiguate these and it’s by the module name:
fromRequestMsg whichEntity =
case whichEntity of
Module1.Entity1 -> Entity1
Module1.Entity2 -> Entity2
But this strikes me as so utterly non-obvious as to be almost intentionally contrived. When I am thinking about my union types, I think of the variants as members of the type not members of the module and so my first inclination on how to reference / instantiate / disambiguate them is by dereferencing the type, not the module! This is especially the case if you are coming from places like Java, C++, Python, C#, Rust, etc as I of course am and I suspect many are, where enum
members often can’t exist in isolation, and must be dereferenced from the overarching type name.
So my question is why doesn’t this syntax exist? Why are type
s not considered namespaces?
I have to imagine there’s a reason and I’d like to understand why so I don’t go developing bad opinions that are poorly informed
If there is no reason and this is some oversight for years and years, can I formerly suggest it?