【问题标题】:Getting a list of all possible data type values in Haskell在 Haskell 中获取所有可能的数据类型值的列表
【发布时间】:2011-05-17 00:08:55
【问题描述】:

如果我有一个数据类型说:

data Color = Red | Yellow | Green

有没有办法可以把它变成一个 [Color] 类型的列表来获取所有可能的值? [红、黄、绿]

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

【问题讨论】:

  • 我相信 [toEnum 0 ..] 无论您如何更改数据定义都有效。

标签: list haskell types


【解决方案1】:

不确定它是否是反模式(我现在也想不出有什么好的用途),但有可能。使用Enum(允许生成类似[someCtor .. someOtherCtor] 的列表)和Bounded(用于minBoundmaxBound)类型类。幸运的是,您可以同时导出两者:

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

allColors = [(minBound :: Color) ..]

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

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

【讨论】:

    【解决方案2】:

    当然,delnan 的答案更好。由于我不知道如何在评论中包含一段代码,因此我将在此处给出一个概括作为单独的答案。

    allValues :: (Bounded a, Enum a) => [a]
    allValues = [minBound..]
    

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

    allColors :: [Color]
    allColors = allValues
    

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

    【讨论】:

    • 我同意你的观点,因为 Delnan 的解决方案不需要对类型中的实际值进行任何引用。在一个 SO 说明中,也许我接受得太快了,但亚当斯的回答确实按照我的要求工作。
    • +1 好点。 (您可以像往常一样在 cmets 中使用反引号,但会删除换行符 - 而且,这不适合评论,无论如何您都应该得到代表 :))
    【解决方案3】:
    data Color = Red
               | Yellow
               | Green
               deriving Enum
    
    allColors = [Red ..]
    

    【讨论】:

    • 当我们添加| Pink时,这将被打破。
    • 我相信 [toEnum 0 ..] 无论您如何更改数据定义都有效。
    【解决方案4】:

    这里是使用 Parsec 解析枚举的示例

    data FavoriteColor = Maroon | Black | Green  | Red | 
                         Blue   | Pink  | Yellow | Orange
                                 deriving (Show, Read, Enum, Bounded)
    

    还有解析器解析器

    parseColor :: Parser FavoriteColor           
    parseColor = fmap read . foldr1 (<|>) $ map (try . string . show) 
      [ minBound :: FavoriteColor ..] 
    

    当然,可以通过模式匹配更好地应用尝试,其他一些事情可以使它更好,但这只是该技术的一些使用示例。

    【讨论】:

      猜你喜欢
      • 2017-02-27
      • 2013-08-16
      • 2021-07-02
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多