Можно ли перебирать тип соединения в Elm?
У меня есть тип объединения цветов, которые я хочу отобразить пользователю. Можно ли перебирать все значения объединения типов?
type Color = Red | Blue | Green | Black
colorToStirng color =
case color of
Red -> "red"
Blue -> "blue"
Green -> "green"
Black -> "black"
colorList =
ul
[]
List.map colorListItem Color -- <- this is the missing puzzle
colorListItem color =
li [class "color-" ++ (colorToString color) ] [ text (colorToString color) ]
Ответы
Ответ 1
К сожалению, нет. Это невозможно.
Для простого типа с конечным числом значений, таких как ваш тип Color
, может показаться, что компилятор должен иметь возможность генерировать такой список. Тем не менее, если речь идет о комплименте, нет никакой разницы между типом и типом типа
type Thing = Thing String
Для повторения всех значений типа Thing
потребуется выполнить итерацию по всем значениям типа String
.
Ответ 2
Проблема с объявлением функции вроде:
type Foo
= Bar
| Baz
enumFoo =
[ Bar
, Baz ]
является то, что вы, вероятно, забудете добавить новые перечисления к нему. Чтобы решить эту проблему, я играл с этой (хакерской, но менее хакерской, чем идея выше) идеей:
enumFoo : List Foo
enumFoo =
let
ignored thing =
case thing of
Bar -> ()
Baz -> ()
-- add new instances to the list below!
in [ Bar, Baz ]
Таким образом, вы по крайней мере получите ошибку для функции и, надеюсь, не забудьте добавить ее в список.
Ответ 3
Конечно, вы можете это сделать. Просто не автоматически через компилятор.
type Foo
= Bar
| Baz
| Wiz
-- just write this for types
-- you wish to use as enumerations
enumFoo =
[ Bar
, Baz
, Wiz ]
Это работает отлично, но, очевидно, было бы лучше и исчерпывающе проверено, если перечисление всегда поддерживается компилятором.
colorList =
ul
[]
List.map colorListItem enumFoo