Let us consider the following code snippet:
blah :: a -> b -> a
blah x y = ble x where
ble :: b -> b
ble x = x
This compiles fine under GHC, which essentially means that b
from the 3rd line is something different than b
from the first line.
My question is simple: is there a way to somehow relate in the type declaration of ble
to a type used in an outer context, i.e. the type declaration of blah
?
Obviously, this is just an example and not a real-world use-case for type declarations.
This is possible with the ScopedTypeVariables extension. You need to use explicit forall's to bring the type variables into scope.
Trying to load this definition with ScopedTypeVariables enabled gives:
You can tell that GHC interprets the two
b
s as the same type because the error says thata
andb
are bound on the same line.If you don't want to use ScopedTypeVariables, you can use the good ole fashion
asTypeOf
function.Of course, this won't compile because of the type error.
Update:
I would like to point out that sometimes you might have to be a little crafty to do what you want with
asTypeOf
. Take the following example that superflously usesasTypeOf
because I don't want to think of a case that actually needsasTypeOf
. Similar solutions would work the same for real world cases.