2017-03-11 12 views
1

列挙型は、整数とのマッピングが可能な型を表します。等価ではない列挙型の比較可能性

整数は同等かどうかテストできます。

Eqを必要としないEnumのインスタンスがありますか?

+0

「Enum」の標準インスタンスはすべて、「Eq」のインスタンスでもあると思います。なぜそうであってはならないのか、私は考えることができません。 – chi

+1

私はあなたの質問をよく理解していません - それが役に立つと思われる例がほしいですか? – epsilonhalbe

+1

私はかつてターミナルカラー用のデータ型を作成し、from/toEnum関数を使用してターミナルエスケープコードを作成しました。何らかの理由でプロダクションコードに平等が求められない場合は、テストコードに孤立したインスタンスを置くことができます。最も必要なのはEq – epsilonhalbe

答えて

3

Intがバインドされているため、Enumのみで平等テストを行うには不十分です。私たちが次のような機能を持っていたとしましょう。

eqEnum :: Enum a => a -> a -> Bool 
eqEnum x y = fromEnum x == fromEnum y 

今、私たちは一致していない2 Integerを生成することができます

ghci> eqEnum 0 (2 + 2 * toEnum (maxBound :: Int)) 
True 

またDoubleをチェックすることができます。

まあ
ghci> eqEnum 3.0 pi 
True 

、おっと。 Enumは、正しいEqインスタンスを生成しません。私たちも、少しさらに行くとEqインスタンスを持つことができないタイプのためEnumのインスタンスを作成することができます。

newtype Foo = Foo { unFoo :: Integer -> Integer } 

instance Enum Foo where 
    fromEnum (Foo f) = fromEnum $ f 0 
    toEnum n  = Foo (+ toInteger n) 
    succ    = Foo . succ . unFoo -- not necessary 
    pred    = Foo . pred . unFoo -- not necessary 

我々は機能F_n(x) = x + nの家族を列挙している偽のインスタンスを使用することができます。

> map ((\f -> unFoo f 0) . toEnum) [0..100] 
[0,1,2,...,100] 

ただし、2つの関数が同じであるかどうかは判断できません。

ghci> toEnum . fromEnum $ pi :: Double 
3.0 
ghci> let f = toEnum . fromEnum $ Foo (const 0) :: Foo 
ghci> unFoo f 0 
0 
ghci> unFoo f 1 -- not constant anymore 
1 

基本的な問題はEnumは何の法律を持っていないということです。そして、それはDoubleであるとして、多くのFootoEnum . fromEnumと、実際に回復不可能な値があります。からIntに変換する必要があります。しかし、結局のところ、それはoriginally meant for [x..y](別名enumFromTo x y)であることを示して、あまり驚くべきことではありません。

関連する問題