Constraints for Recursive Types

142 Views Asked by At

I have a type data A a = B (a (A a)). How can I put a constraint on the type var a in function something :: Eq (a b) => A a -> SomeType?

1

There are 1 best solutions below

2
On

It's not completely clear to me what you want to achieve, but this compiles:

{-# LANGUAGE QuantifiedConstraints, StandaloneDeriving, UndecidableInstances #-}

data A a = B (a (A a))

deriving instance (forall t. Eq t => Eq (a t)) => Eq (A a)

something :: (forall t. Eq t => Eq (a t)) => A a -> String
something x 
   | x==x      = "hello"
   | otherwise = "world"

The trick here is to require that Eq (a t) holds for any possible t. That requires QuantifiedConstraints.

Of course, you can also use a more modest approach and require instead

something :: Eq (a Bool) => A a -> String

but that won't allow you to use == on the argument.

Alternatively,

something :: Eq (A a) => A a -> String

should work, even if it triggers a warning.