我正在关注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类型?我是否必须实现它定义的所有功能?我认为这些都是在你派出那门课时实现的。
答案 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..]
的列表,这可能不是您想要的。
因此,我建议您手动将Enum
与Bounded
一起实施,以使其满足rules given in the documentation of Enum
。
我想所有这些东西都可以使用Template Haskell自动生成。这将成为一个有趣的图书馆。