5

HaskellのWikiページのアドバイスに従っていました:コードのパフォーマンスを向上させるためのパフォーマンス/データ型ですが、変更したとき

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'

列挙型をあまり使用していませんが、Colorを列挙型に変換するにはどうすればよいですか?定義されているすべての機能を実装する必要がありますか?そのクラスを派生させたときに、それらはすべて実装されたと思いました。

4

2 に答える 2

10

GHCのアドバイスが悪い場合もありますが、この場合は適切です。ファイルの先頭に、

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

GeneralizedNewtypeDerivingは、一部のクラスを表現のインスタンスに「転送」するように指定できる言語拡張機能です。つまり、'sを使用するだけで'インスタンスnewtype Color = Color Int deriving (Enum)を実装することを意味します(GHCが生成する必要なラッピング/アンラッピングの後)。ColorEnumInt

しかし、これが必要な唯一の理由である場合はEnum、それを省略して実行することもできます

(yellow:red:green:blue:empty:_) = map Color [1..]
于 2012-12-07T10:30:20.817 に答える
4

導出することによりEnum、部分的に正しい実装しか得られないことに注意してください。たとえば、enumFrom yellowはと同等のリストを返しますがmap Color $ [1..]、これはおそらくあなたが望むものではありません。

したがって、のドキュメントに記載されているルールを満たすように、手動でEnum一緒に実装することをお勧めします。BoundedEnum

テンプレートHaskellを使えば、これらすべてのものを自動的に生成できると思います。これは面白いライブラリになります。

于 2012-12-07T12:07:56.643 に答える