Julian Birch
Julian Birch

Reputation: 2748

Testing a type for (Eq a) in Haskell

I'm trying to see if I can implement something which branches on whether the type implements Eq.

Here's an attempt:

data HTrue
data HFalse

type family Eq1 (a :: *) where
  Eq1 (Eq x) = HTrue
  Eq1 a = HFalse

You'll note that I put (a :: *) in the code. That's because if I don't, the code compiles, but generates Eq1 as a constraint, while I actually want it to be a closed type family.

Is there any way to get this to work?

Upvotes: 2

Views: 303

Answers (1)

MigMit
MigMit

Reputation: 1697

The set of instances, visible in different contexts, is also different, so any such function would be very dangerous. Seriously, don't do that. Consider defining two newtypes like this:

module EqTest (HasEq, NoEq, hasEq, noEq, fromEq)
newtype HasEq a = HasEq a
newtype NoEq a = NoEq a
hasEq :: Eq a => a -> HasEq a
hasEq = HasEq
noEq :: a -> NoEq a
noEq = NoEq
class FromEq c where fromEq :: c a -> a
instance FromEq HasEq where fromEq (HasEq a) = a
instance FromEq NoEq where fromEq (NoEq a) = a

and do not export constructors. You would have to always specify which version you'd like to use, but that's better than relying on class instances.

Upvotes: 4

Related Questions