Fundeps and quantified constructors
Tom Pledger
Tom.Pledger@peace.com
Sat, 3 Feb 2001 17:13:04 +1300
nubie nubie writes:
| So I want to have a polymorphic Collection type, just because.
|
| > class Collection c e | c -> e where
| > empty :: c
| > put :: c -> e -> c
|
| > data SomeCollection e = forall c . Collection c e => MakeSomeCollection c
|
| Hugs (February 2000) doesn't like it. It says
| Variable "e" in constraint is not locally bound
|
| I feel that e *is* bound, sort of, because c is bound and there's a
| fundep c->e.
That line of reasoning establishes that e is constrained on the right
hand side of the "=". However, it's still bound (by an implicit
"forall e") on the left hand side of the "=". The problem is that e
can leak details about c to parts of the program outside the "forall
c". It's still a problem if you remove the "| c -> e" fundep.
A more common use of a "Collection c e | c -> e" class is:
data SomeCollection e = --some data structure involving e
instance SomeContext e => Collection (SomeCollection e) e where
--implementations of empty and put, for the aforementioned
--data structure, and entitled to assume SomeContext
Is that collection type polymorphic enough for your purposes?
:
| The following things work as expected:
|
| > data IntCollection = forall c . Collection c Int => MakeIntCollection c
| > data AnyCollection = forall c e . Collection c e => MakeAnyCollection c
Neither of them has a type variable tunnelling through the local
quantifier.
HTH.
Tom