[英]Getting a list of all possible data type values in Haskell
If I have a data type say: 如果我有数据类型,请说:
data Color = Red | Yellow | Green
Is there a way I can turn this into a list of type [Color] getting all possible values? 有没有办法将其转换为[Color]类型的列表,以获取所有可能的值? [Red, Yellow, Green] [红色,黄色,绿色]
Perhaps this is a complete anti pattern? 也许这是一个完整的反模式?
Not sure if it is an anti-pattern (nor can I think of a good use right now), but it's possible. 不知道它是否是反模式(我现在也不能想到一个很好的用法),但是有可能。 Use the Enum
(allows to generate a list like [someCtor .. someOtherCtor]
) and Bounded
(for minBound
and maxBound
) type classes. 使用Enum
(允许生成类似[someCtor .. someOtherCtor]
的列表)和Bounded
(对于minBound
和maxBound
)类型类。 Luckily, you can derive both: 幸运的是,您可以同时导出:
data Color = Red
| Yellow
| Green
deriving (Enum, Bounded)
allColors = [(minBound :: Color) ..]
If you ever add another color, allColors get updated automatically. 如果您添加其他颜色,则allColors将自动更新。 One restriction though: Enum
requires all contructors to be nullary, ie adding Foo Int
breaks the whole thing. 但是有一个限制: Enum
要求所有构造函数均为零,即,添加Foo Int
会破坏整个过程。 Luckily, because a list of all possible values for this would be way too large. 幸运的是,因为所有可能的值列表太大了。
Edit: The other answer works as well, maybe better since it doesn't require deriving Bounded
and is therefore a bit shorter. 编辑:另一个答案也很好,也许更好,因为它不需要派生Bounded
,因此要短一些。 I'll still leave mine because I love over-engineered but extremely generic code ;) 我仍然会离开我,因为我喜欢过度设计但极其通用的代码;)
Surely delnan's answer is better. 当然,德尔南的答案更好。 Since I do not know how to include a piece of code in a comment, I'll give a generalisation as a separate answer here. 由于我不知道如何在注释中包含一段代码,因此在这里我将给出一个概括作为单独的答案。
allValues :: (Bounded a, Enum a) => [a]
allValues = [minBound..]
Now, this works for any type with a Bounded
and Enum
instance! 现在,此方法适用于具有Bounded
和Enum
实例的任何类型! And allColors
is just a special case: 而allColors
只是一个特例:
allColors :: [Color]
allColors = allValues
In many cases, you won't even need to define allColors
separately. 在许多情况下,您甚至不需要单独定义allColors
。
data Color = Red
| Yellow
| Green
deriving Enum
allColors = [Red ..]
Here is an example of using this technique to parse enums with Parsec 这是使用此技术通过Parsec解析枚举的示例
data FavoriteColor = Maroon | Black | Green | Red |
Blue | Pink | Yellow | Orange
deriving (Show, Read, Enum, Bounded)
And the parsec parser 和parsec解析器
parseColor :: Parser FavoriteColor
parseColor = fmap read . foldr1 (<|>) $ map (try . string . show)
[ minBound :: FavoriteColor ..]
of course the try could could be applied by better by pattern matching and a few other things could make it nicer but this is just an example of some usage of the technique. 当然,可以通过模式匹配来更好地应用尝试,而其他一些事情可能会使它变得更好,但这只是该技术的一些使用示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.