2012-04-11 5 views
5

私は最近、 "私にハスケルを学ぶ"ことを試みてきました。生のInteger(型の安全性とコードの明快さ)を使用せずに、整数型を表す新しい型を作成したいと思います。具体的には、次のコードはコンパイルされます。ただしHaskellタイプの「Integralを導出する」タイプが「Enumを導出」する必要があるのはなぜですか?

newtype AuxState = AuxState Integer 
    deriving (Eq, Ord, Num, Integral, Real, Enum) 

、自分のアプリケーション内の状態の無限の数があるので、私は列挙型には、この状態を変換するには関心を持っていません。私はそれだけでderiving (Eq, Ord, Num, Integral, Real)ですのでderiving (Enum)文を削除しようとする場合は、コンパイラは文句:

No instance for (Enum AuxState) 
    arising from the 'deriving' clause of a data type declaration 
Possible fix: 
    add an instance declaration for (Enum AuxState) 
    or use a standalone 'deriving instance' declaration, 
     so you can specify the instance context yourself 
When deriving the instance for (Integral AuxState) 

私はそれは難しいHaskellはまた、列挙型クラスであることをインテグラルクラスの種類を強制することを信じることを見つけます。それはちょうど周りに他の方法であるべきではないですか?これには理由があるのですか、何か間違ったことをやっていますか? Integral数学の基礎がsuccpred操作であるため、

+2

列挙型インスタンスは、順序付けられた型です。それらの値は列挙できます。 Enum型クラスの主な利点は、リスト範囲でその値を使用できることです。彼らはまた、後継者と前任者を定義しました。後者と前者は、succとpredfuctionsで得ることができます。私はすべての整数がこのクラスに属するべきだと信じています、どうしてあなたのものではないはずですか? –

+1

"しかし、私のアプリケーションには無限の状態があるので..."あなたは「Enum」について間違って理解していると思います。 'Enum'は有限個の値を持つ型を意味するものではありません。 – newacct

+1

"それ以外の方法ではいけませんか?" 'Double'は' Enum'ですが、明らかに 'Integral'ではありません – newacct

答えて

8

すべてIntegralは必ずしもEnumです。 (技術的にはEnumはタイプタイプがIntegralの数学的なセミグループであると考えています)。もう1つの方法はもっと間違っているようです。つまり、EnumはすべてIntegralであるはずですか?これにはランダムなADTが含まれますか?

data Foo = A | B | C | D | E | F | G deriving (Enum) 

(すべてEnumは確か、Integralのサブセットに同形であるべきであるが、それは実際には他の方向に行く示唆している:。Integralその逆任意Enumを表すことはできませんが、そうIntegralはur- Enumの一種である)

+0

私は 'Integral'は半グループではないと言います。ユークリッドのドメイン(つまり、素晴らしい種類のリング)ですが、いくつかの追加の制限があります。 –

6

次のようにIntegralPreludeで定義されているのでので、技術的な理由は次のとおりです。

class (Real a, Enum a) => Integral a where 
    ... 

数学的な理由は、すべての整数型が可算であるということですが、ありません逆も同様です。たとえば有理数を考えてみましょう。 EnumはIntegerで示されるように有限列挙を意味しないことに注意してください。

関連する問題