How can I trigger a type error in Haskell?

Viewed 642

Let's suppose I have a type

data F a = A a | B

I implement the function f :: F a -> F a -> F a like this:

f (A x) B = A x
f B (A _) = B
f (A _) (A x) = A x

However no such thing as f B B it's logically impossible, so I want:

f B B = GENERATE_HASKELL_COMPILE_ERROR

which is not working of course. Omitting definition or using f B B = undefined is not a solution, because it generates runtime exception. I'd like to get a compile time type error.

The compiler has all the information, it should be able to deduce I made a logic error. If say I declare let z = f (f B (A 1)) B that should be an immediate compile time error and not some runtime exception which can hide in my code for years.

I have found some info about contracts but I do not know how to use them here, and I'm curious if there is any standard way to do this in Haskell.


EDIT: it's turned out, what I was trying to do is called dependent type which is not fully supported in Haskell (yet). Nevertheless it's possible to generate type error using index types and several extensions. David Young's solution seems to be more straightforward approach while Jon Purdy is using type operators creatively. I accept the first but I like both.

3 Answers
Related