Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I define an instance for a specific type application in Haskell 98?

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

instance Enum a => Arbitrary (Set a)

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

instance Arbitrary (Set Int)

or

instance a ~ Int => Arbitrary (Set a)
like image 259
dfeuer Avatar asked Aug 05 '16 18:08

dfeuer


People also ask

How do you define a type class in Haskell?

A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.

What does deriving show do in Haskell?

Deriving means that your data type is automatically able to "derive" instances for certain type classes. In this case BaseballPlayer derives Show which means we can use any function that requires an instance of Show to work with BaseballPlayer .


1 Answers

This is possible using an idea I think I first encountered in a paper by Oleg Kiselyov, and which underlies 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

Now I can use

instance IsInt a => Arbitrary (Set a)

and be confident that I'm really dealing with Int. For convenience, I can constrain the IsInt class with any classes I need of which Int is an instance:

class (Show a, Read a, Integral a, Arbitrary a) => IsInt a where ...
like image 57
dfeuer Avatar answered Sep 18 '22 14:09

dfeuer