Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to relate to type from outer context

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.

like image 570
julx Avatar asked Dec 06 '11 12:12

julx


1 Answers

This is possible with the ScopedTypeVariables extension. You need to use explicit forall's to bring the type variables into scope.

blah :: forall a b. a -> b -> a blah x y = ble x where     ble :: b -> b     ble x = x 

Trying to load this definition with ScopedTypeVariables enabled gives:

foo.hs:2:16:     Couldn't match type `a' with `b'       `a' is a rigid type variable bound by           the type signature for blah :: a -> b -> a at foo.hs:2:1       `b' is a rigid type variable bound by           the type signature for blah :: a -> b -> a at foo.hs:2:1     In the first argument of `ble', namely `x'     In the expression: ble x     In an equation for `blah':         blah x y           = ble x           where               ble :: b -> b               ble x = x 

You can tell that GHC interprets the two bs as the same type because the error says that a and b are bound on the same line.

like image 131
John L Avatar answered Oct 03 '22 09:10

John L