How to declare polymorphic instances for higher-kinded types?
andres at well-typed.com
Mon Mar 5 13:40:31 CET 2012
> If I get it right, the trick is to use a *-kinded (instead of a
> *->*-kinded) argument for the class & instances and have a "type
> function" that is able to phantom-retag an already applied
> type-constructor `Foo_ Unres` to a differently applied type-constructor
> `Foo_ Res`.
> The only thing that disturbs me is that I have to define explicit
> boilerplate type family declarations for all twenty or so
> non-polymorphic instances which'd look always the same, i.e.
> type ResFun (t r) a = t a
> type ResArg (t r) a = t ~ a
> ...could that be defined as an override-able default somehow?
The only way I can quickly think of that might work is to go via
another type family. However, this requires "UndecidableInstances":
type family GetF e :: Resolved -> *
type instance GetF (f x) = f
-- provides operation to transform an unresolved `Foo_ Unres` to a
resolved `Foo_ Res`
class Resolvable e where
type ResFun e (a :: Resolved) :: *
type ResFun e a = GetF e a
type ResArg e (a :: Resolved) :: Constraint
type ResArg e a = GetF e a ~ e
Then, for types like Foo, you can just write:
instance Resolvable (Foo_ r) where
resolve _ x = return Foo
I.e., you shouldn't need the type family declarations.
Andres Löh, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com
More information about the Glasgow-haskell-users