获取Haskell中所有可能的数据类型值的列表

Guy*_*Guy 34 haskell types list

如果我有数据类型说:

data Color = Red | Yellow | Green
Run Code Online (Sandbox Code Playgroud)

有没有办法可以将其转换为[Color]类型列表获取所有可能的值?[红色,黄色,绿色]

也许这是一个完整的反模式?

小智 59

不确定它是否是反模式(我现在也不能想到好用),但它是可能的.使用Enum(允许生成类似的列表[someCtor .. someOtherCtor])和Bounded(for minBoundmaxBound)类型类.幸运的是,你可以得到两者:

data Color = Red
           | Yellow
           | Green
           deriving (Enum, Bounded)

allColors = [(minBound :: Color) ..]
Run Code Online (Sandbox Code Playgroud)

如果您添加其他颜色,allColors会自动更新.但是有一个限制:Enum要求所有的构造函数都是无效的,即添加Foo Int破坏整个东西.幸运的是,因为所有可能值的列表会太大.

编辑:另一个答案也可以,也许更好,因为它不需要派生Bounded,因此有点短.我仍然会离开我,因为我喜欢过度设计但非常通用的代码;)


Ozg*_*gur 40

当然,德尔南的答案更好.由于我不知道如何在评论中包含一段代码,因此我将在此处作为单独的答案进行概括.

allValues :: (Bounded a, Enum a) => [a]
allValues = [minBound..]
Run Code Online (Sandbox Code Playgroud)

现在,这适用于任何带有BoundedEnum实例的类型!而且allColors只是一个特例:

allColors :: [Color]
allColors = allValues
Run Code Online (Sandbox Code Playgroud)

在许多情况下,您甚至不需要allColors单独定义.

  • 我同意你的意见,因为Delnan的解决方案不需要任何类型的实际价值.在SO注释中,也许我接受得太快了,但adamse的答案确实与我的要求一致. (2认同)

ada*_*mse 33

data Color = Red
           | Yellow
           | Green
           deriving Enum

allColors = [Red ..]
Run Code Online (Sandbox Code Playgroud)

  • 我相信无论你如何改变数据定义,`[toEnum 0 ..]`都有效. (6认同)
  • 当我们添加`|时,这会崩溃 Pink`. (4认同)