Is it possible to iterate over union type in Elm?
The problem with declaring a function like:
type Foo
= Bar
| Baz
enumFoo =
[ Bar
, Baz ]
is that you will probably forget to add new enums to it. To solve this, I've been playing with this (hacky, but less hacky than the idea above) idea:
enumFoo : List Foo
enumFoo =
let
ignored thing =
case thing of
Bar -> ()
Baz -> ()
-- add new instances to the list below!
in [ Bar, Baz ]
This way you at least get an error for the function and hopefully don't forget to add it to the list.
Unfortunately, no. It is not possible.
For a simple type with a finite number of values like your Color
type it might seem like the compiler should be able to generate such a list. As far as the complier is concerned though, there is no difference between your type and a type like
type Thing = Thing String
To iterate over all the values of type Thing
would then require iterating over all the values of type String
.
This does not exactly answer your question, but since Elm is so similar to Haskell, I am probably not the only one wondering what the Haskell side of the story is.
So in Haskell (showing ghci) you can do:
Prelude> data Color = Red | Blue | Green | Black deriving (Show, Bounded, Enum)
Prelude> [minBound..maxBound]::[Color]
[Red,Blue,Green,Black]
Maybe a future version of elm will borrow from that.
Edit: I found Getting a list of all possible data type values in Haskell which also answers this.
Oh course you can do it. Just not automatically via the compiler.
type Foo
= Bar
| Baz
| Wiz
-- just write this for types
-- you wish to use as enumerations
enumFoo =
[ Bar
, Baz
, Wiz ]
This works just fine, but obviously would be nicer and exhaustivity checked, if enumeration is ever supported by the compiler.
colorList =
ul
[]
List.map colorListItem enumFoo