Higher rank types look like great fun. From the Haskell wikibook comes this example:
foo :: (forall a. a -> a) -> (Char,Bool)
foo f = (f \'c\', f True)
>
Weirich and Washburnn's "Boxes go Bananas"! (paper, slides)
Here is a very crude and probably slightly inaccurate explanation of what it's all about: given an inductive type, BGB lets you represent the space of functions from that type which are "positive" -- they never case-discriminate on their arguments. At most they include their arguments as part of other values (usually of the same type).
Weirich+Washburn use this to get a probably-adequate HOAS representation of the lambda calculus in -XRankNTypes
Haskell (has anybody proven it adequate yet?).
I use it here (warning: messy code) to turn a
(forall g . GArrow g => g () x -> g () y)
into a
(forall g . GArrow g => g x y)
This works because the rank-2 polymorphic type can't "inspect" the structure of its argument -- all it can do is "paste" that argument into bigger structures. Some trickery lets me figure out where the pasting happens, and then I thread the pasting point(s) (if any) back out to the input of the GArrow.
You can't do this with the Control.Arrow
class, because the whole Haskell function space "leaks" into it via arr
.