2012-10-22 40 views
3

我的代码片段看起来是这样的:有没有一种简单的方法可以将派生Enum的数据类型转换为列表?

data SomeData = A | B | C | D | E deriving (Show, Enum) 

,我希望能够达到一定的数值​​容易映射到这些类型。说我想有映射到SomeDatachar S,我可能会做它像这样:

mappings = zip "abcde" [A, B, C, D, E] 

这将产生[('a',A),('b',B)...]等。我希望Enum类型的类可以让我能够通过使用一些便利功能将数据类型转换成上面列出的列表([A, B, C, D, E]),从而轻松完成此操作。

标准库中是否有这样的功能?或者如果我想使用类似的东西,我是否需要自己定义它?

回答

3

一般来说,我会做

mappings = zip "abcde" [A..] 

,但我会很诱惑与

mappings = zip ['a' ..] [A ..] 

去,这样,如果我添加其他字母后,代码将更新。

与最大限度地面向未来的工作走向我定义

import Data.Char 

data SomeData = A | B | C | D | E deriving (Show, Enum, Bounded) 

allData :: SomeData 
allData = enumFrom minBound 

mapppings = zip (map (toLower.head.show) allData) allData 

,我正在做关于未来的唯一assumtion是,它由单个字母。

但是,这是玩,实际上并没有那么清楚。

2

其实,你可以使用一个范围。

[A .. E] 

正如在无价的Learn You A Haskell中所述。

1

试试这个在ghci中

> [A ..] 
[A,B,C,D,E] 
5

如果您还派生Bounded,那么你甚至可以做到这一点没有明确地知道了“最小”的构造函数的名字是什么:

Prelude> data SomeData = A | B | C | D | E deriving (Show, Enum, Bounded) 
Prelude> [minBound :: SomeData ..] 
[A,B,C,D,E] 
2

添加Bounded到您的派生,你可以做[minBound ..]获得一个完整的列表。

7

你可以去更通用:

-- added deriving Bounded 
data SomeData = A | B | C | D | E deriving (Show, Enum, Bounded) 

fullRange :: (Bounded a, Enum a) => [a] 
fullRange = enumFromTo minBound maxBound 

和(如果需要具有明确的类型标注:fullRange :: [SomeData]),那么只需要调用fullRange

相关问题