Skip to content

Instantly share code, notes, and snippets.

@Icelandjack
Created May 27, 2017 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Icelandjack/e42495341f6029aad8c7e4e4a12c34ce to your computer and use it in GitHub Desktop.
Save Icelandjack/e42495341f6029aad8c7e4e4a12c34ce to your computer and use it in GitHub Desktop.
Define multiple instances simultaneously

Idea from https://gist.github.com/Icelandjack/e1ddefb0d5a79617a81ee98c49fbbdc4

Works great for concrete types

data A = MkA

instance (Eq & Ord & Show & Arbitrary) A where
  (==) :: A -> A -> Bool
  MkA == MkA = True
  
  compare :: A -> A -> Ordering
  MkA `compare` MkA = EQ
  
  show :: A -> String
  show MkA = "MkA"
  
  arbitrary :: Gen A
  arbitrary = pure MkA
@Icelandjack
Copy link
Author

So if inferred from method's required constraints, then we have

instance EOSA (B b) where
  a == b = compare a b == EQ
  MkB a `compare` MkB b = compare a b

resulting in

instance Ord a => Eq  (B b)
instance Ord a => Ord (B b)

@Icelandjack
Copy link
Author

We merge the contexts of methods from the same type class just as usual

class  EQ a where  eq :: a -> a -> Bool
class NEQ a where neq :: a -> a -> Bool

newtype C a = C a
  deriving (EQ, NEQ)

instance (EQ a, NEQ a) => Eq (C a) where
  (==) = eq
  (/=) = neq

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment