2016-08-05 21 views
7

私はData.Setのためのテストスイートはだけは本当にa ~ Intのための賢明Arbitrary Set aを定義しますが、特別なGHC ~を回避することがHaskell 98で特定のタイプのアプリケーションのインスタンスを定義するにはどうすればよいですか?

私だけ Arbitrary (Set Int)インスタンスがどのGHC拡張を必要とせずに使用されていることを確認するにはどうすればよい
instance Enum a => Arbitrary (Set a) 

を使用していることに気づきました? GHCのみのコードでは、私は、これは私が私が最初にオレグKiselyovによって紙に遭遇したと思うアイデアを使用して可能である

instance Arbitrary (Set Int) 

または

instance a ~ Int => Arbitrary (Set a) 

答えて

6

のいずれか、その後FlexibleInstancesGADTsのいずれかを使用したいですControl.Lens.Equalityの下にある。

import Data.Functor.Identity 

class IsInt a where 
    fromIntF :: f Int -> f a 

instance IsInt Int where 
    fromIntF fx = fx 

toIntF :: IsInt a => g a -> g Int 
toIntF = unf . fromIntF . F $ id 

newtype F g a b = F {unf :: g b -> a} 

fromInt :: IsInt a => Int -> a 
fromInt = runIdentity . fromIntF . Identity 

toInt :: IsInt a => a -> Int 
toInt = runIdentity . toIntF . Identity 

今私は

instance IsInt a => Arbitrary (Set a) 

を使用して、私は本当にIntを扱ってることを確信することができます。便宜上、私はIntがインスタンスである私が必要とするすべてのクラスでIsIntクラスを制約することができます

class (Show a, Read a, Integral a, Arbitrary a) => IsInt a where ... 
+3

それは言及する価値があるかもしれない:これはあなたのシステムの外側ではなく、その中あなたが望む保証を提供します。すなわち、GHCは '' Int'''から '' IsInt a''を推論しません。これは、しばしば煩わしい追加型アノテーションを必要とする場合があります。私はそれが純粋にH98(またはH2010)の中で助けられるとは思わない。 –

+0

@DanielWagnerはい、GHCのアプローチよりもはるかに劣っています。平等制約が標準化されているなら、私は間違いなくそれを好むでしょう。しかし、「コンテナ」は一般的に可能な限り「ポータブル」であるようにしています。したがって、私が拡張機能なしで必要なものを行うことができるなら、私は行います。 – dfeuer

+1

@DanielWagner、この実装がGHCのものと互換性があることに気付くこともあります。 'fromIntF'を' Refl :: Int:〜:Int'に適用して、 'IsInt a => Int:〜 :a'。実際、これは言語にどのように適合するかにかかわらず、これと同等の平等型でも機能します。 – dfeuer

関連する問題