How to define an instance for an application of a certain type in Haskell 98?

I noticed that the test set for Data.Set really defines the Arbitrary Set a reasonably for a ~ Int , but to avoid the special GHC ~ , it uses

 instance Enum a => Arbitrary (Set a) 

How can I make sure that only an Arbitrary (Set Int) instance is used without any GHC extensions? In the GHC code, I would use either FlexibleInstances or GADTs , and then

 instance Arbitrary (Set Int) 

or

 instance a ~ Int => Arbitrary (Set a) 
+7
haskell typeclass
source share
1 answer

This is possible using an idea that I seem to have first encountered in an article by Oleg Kiselev and which underlies Control.Lens.Equality .

 import Data.Functor.Identity class IsInt a where fromIntF :: f Int -> fa instance IsInt Int where fromIntF fx = fx toIntF :: IsInt a => ga -> g Int toIntF = unf . fromIntF . F $ id newtype F gab = F {unf :: gb -> a} fromInt :: IsInt a => Int -> a fromInt = runIdentity . fromIntF . Identity toInt :: IsInt a => a -> Int toInt = runIdentity . toIntF . Identity 

Now i can use

 instance IsInt a => Arbitrary (Set a) 

and rest assured that I'm really dealing with Int . For convenience, I can limit the IsInt class IsInt any classes I need, Int is an instance:

 class (Show a, Read a, Integral a, Arbitrary a) => IsInt a where ... 
+6
source share

All Articles