是否可以在 Elm 中迭代联合类型?

Is it possible to iterate over union type in 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) ]

很遗憾,没有。不可能。

对于像您的 Color 类型这样具有有限数量值的简单类型,编译器似乎应该能够生成这样的列表。不过,就编译器而言,您的类型与

之类的类型没有区别
type Thing = Thing String

要遍历 Thing 类型的所有值,则需要遍历 String.

类型的所有值

哦,当然可以。只是不会自动通过编译器。

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

声明函数的问题:

type Foo 
  = Bar 
  | Baz

enumFoo = 
  [ Bar 
  , Baz ]

是您可能会忘记向其中添加新的枚举。为了解决这个问题,我一直在玩这个(hacky,但不像上面的想法那么hacky)想法:

enumFoo : List Foo
enumFoo =
  let
    ignored thing =
      case thing of
          Bar ->  ()
          Baz -> ()
          -- add new instances to the list below!
  in [ Bar, Baz ]

这样你至少会得到一个函数错误,希望不要忘记将它添加到列表中。

这并不能完全回答您的问题,但由于 Elm 与 Haskell 非常相似,我可能不是唯一想知道故事的 Haskell 方面是什么的人。

所以在 Haskell(显示 ghci)you can do

Prelude> data Color = Red | Blue | Green | Black deriving (Show, Bounded, Enum)
Prelude> [minBound..maxBound]::[Color]
[Red,Blue,Green,Black]

也许未来版本的 elm 会借鉴它。

编辑:我发现 Getting a list of all possible data type values in Haskell 也回答了这个问题。