在haskell中将枚举转换为类似int的类型

时间:2012-12-07 10:28:00

标签: haskell enums

我正在关注Haskell的Wiki页面上的建议:Performance/Data types以提高我的代码的性能,但是当我改变时

data Color = Yellow | Red | Green | Blue | Empty deriving (Show, Eq)

newtype Color = Color Int deriving (Eq,Ord,Enum) 
(yellow:red:green:blue:empty:_) = [Color 1 ..]

正如文章中所建议的那样,GHC说:

Can't make a derived instance of `Enum Color':
  `Color' must be an enumeration type
  (an enumeration consists of one or more nullary, non-GADT constructors)
  Try -XGeneralizedNewtypeDeriving for GHC's newtype-deriving extension
In the newtype declaration for `Color'

我没有多次使用Enums,如何将Color变成Enum类型?我是否必须实现它定义的所有功能?我认为这些都是在你派出那门课时实现的。

2 个答案:

答案 0 :(得分:10)

有时GHC的建议很糟糕,但在这种情况下,它的确有点出现。在文件的顶部,输入

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

GeneralizedNewtypeDeriving是一种语言扩展,允许您指定某些类应“转发”到其表示的实例。也就是说,newtype Color = Color Int deriving (Enum)表示仅使用Color来实现Enum的{​​{1}}实例(经过一些必要的包装/解包,GHC为您生成)。

但如果这是你需要Int的唯一原因,你也可以省略它而只是做

Enum

答案 1 :(得分:4)

请注意,通过派生Enum,您只能获得部分正确的实现。例如,enumFrom yellow将返回相当于map Color $ [1..]的列表,这可能不是您想要的。

因此,我建议您手动将EnumBounded一起实施,以使其满足rules given in the documentation of Enum

我想所有这些东西都可以使用Template Haskell自动生成。这将成为一个有趣的图书馆。