mkUltra
mkUltra

Reputation: 3068

Is it possibile to negate type parameter constraint in Haskell?

In Haskell, it's possible to add constraints to a type parameter.

For example:

foo :: Functor f => f a

The question: is it possible to negate a constraint?

I want to say that f can be anything except Functor for example.

UPD:

So it comes from the idea of how to map the bottom nested Functor. Let's say I have Functor a where a can be a Functor b or not and the same rules works for b.

Upvotes: 3

Views: 394

Answers (1)

leftaroundabout
leftaroundabout

Reputation: 120751

Reasons why this is not possible: (basically all the same reason, just different aspects of it)

  • There is an open-world assumption about type classes. It isn't possible to prove that a type is not an instance of a class because even if during compilation of a module, the instance isn't there, that doesn't mean somebody doesn't define it in a module “further down the road”. This could in principle be in a separate package, such that the compiler can't possibly know whether or not the instance exists.
    (Such orphan instances are generally quite frowned upon, but there are use cases for them and the language doesn't attempt to prevent this.)
  • Membership in a class is an intuitionistic property, meaning that you shouldn't think of it as a classical boolean value “instance or not instance” but rather, if you can prove that a type is an instance then this gives you certain features for the type (specified by the class methods). If you can't prove that the type is an instance then this doesn't mean there is no instance, but perhaps just that you're not smart enough to prove it. (Read, “perhaps that nobody is smart enough”.)
    This ties back to the first point: the compiler not yet having the instance available is one case of “not being smart enough”.
  • A class isn't supposed to be used for making dispatch on whether or not a type is in it, but for enabling certain polymorphic functions even if they require ad-hoc conditions on the types. That's what class methods do, and they can come from a class instance, but how could they come from a “not-in-class instance”?

Now, all that said, there is a way you can kind of fake this: with an overlapping instance. Don't do it, it's a bad idea, but... that's the closest you can get.

Upvotes: 7

Related Questions