#3714: Improve error message if an associated family declaration has excess
parameters
---------------------------+------------------------------------------------
Reporter: simonpj | Owner: chak
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 6.10.4
Resolution: | Keywords:
Difficulty: | Os: Unknown/Multiple
Testcase: | Architecture: Unknown/Multiple
Failure: None/Unknown |
---------------------------+------------------------------------------------
Comment (by simonpj):
I'm getting there slowly. If you write
{{{
type family T1 f :: * -> * -- T1 has one type index parameter
type instance T1 [f] e = e
}}}
you get the error
{{{
Tf.hs:7:0:
Number of parameters must match family declaration; expected 1
In the type synonym instance declaration for `T1'
}}}
Now I think Martijn is actually doing this
{{{
type family T2 f e :: * -- T2 has two type indices, f and e
type instance T2 [f] e = e
}}}
This means that `T2` gets arity 2, and has two type indices. In principle
you could give another `type instance` that dispatches on the second
parameter:
{{{
type instance T2 f Char = [f]
}}}
although I don't think Martijn intends that.
Returning to `T1`, could we reasonably expect to declare a `type instance`
with two parameters like this?
{{{
type instance T1 [f] e = e
}}}
No, we could not. T1 is declared to have arity 1, so GHC ensures that it
is saturated (appears applied to one argument). So it'd be fine to write
the type `Monad (T [f])` for exmaple. But with the above instance, `T
[f]` is in effect a type synonym; or if you like `T [f]` is `\e.e`. So it
should not appear un-saturated. So T1's arity depends on its argument.
This is not good. That's the reason for the rule.
However, if we had a way to distinguish type indices from type parameters,
we could say
{{{
type family T3 f !e :: * -- The ! indicates a type parameter (not
an index)
type instance T3 [f] e = e
}}}
This would say
* `T3` has arity 2 and must always appear applied to two arguments
* Only `f` is an index, so only `f` can be instantiated in a `type
instance`
Note that the indices would not necessarily be the first parameters,
although they usually will be.
This would extend naturally to associated types, so you could write this,
just as Martijn wishes:
{{{
class C f where
type T4 f !e :: *
}}}
Interesting.
Simon
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3714#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs