-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Typeclass Definition "Forgets" constraints on functionally dependent type parameter #1340
Comments
This issue doesn't seem to be related to functional dependencies. I can reproduce it with the following, (coalton-toplevel
(define-class (C :col :elem))
(define-class (Eq :elem => EqC :col :elem))
(define-instance (C (List :elem) :elem))
(define-instance (Eq :elem => EqC (List :elem) :elem))) and the same error comes from (coalton-toplevel
(define-class (C :col :elem))
(define-class (Eq :elem => EqC :col :elem))
(define-instance (C (List :elem) :elem))
(define-instance (EqC (List :elem) :elem))) See #1342. Side-note: You can define classes on non- (define-class (Collection :m :a)
(new-collection (Unit -> :m :a))
(add (:a -> :m :a -> :m :a)))
(define-instance (Collection List :a)
(define new-collection (const Nil))
(define add Cons)) allowing you to avoid functional dependencies for this particular use-case. |
Thanks! I'll try rebasing my collections code on your PR and see if it works. This particular code is incomplete, but it's motivated by a desire to define a further typeclass representing maps ("KeyedCollection" in this case) which are also collections of tuples. To be able to get this to typecheck, I had to add the functional dependencies to the (coalton-toplevel
(define-type (ListMap :k :v)
(ListMap (List (Tuple :k :v))))
<functions omitted>
(define-class (KeyedCollection_ :m)
(add-keyed_
(:k -> :v -> :m :k :v -> :m :k :v))
(contains-key_
(Eq :k => :k -> :m :k :v -> Boolean))
(get-val_
(Eq :k => :k -> :m :k :v -> Optional :v))))
(coalton-toplevel
(define-instance (KeyedCollection_ ListMap)
(define add-keyed_ add-keyed-lstmp)
(define contains-key_ contains-key-lstmp)
(define get-val_ get-val-lstmp))
(define-instance (Collection_ (ListMap :k :v) (Tuple :k :v))
(define new-collection_ new-collection-lstmp)
(define add_ add-lstmp)) |
I have two typeclasses with functionally dependent type parameters. The simplest case, with no type constraints compiles:
as does the case where there is a type constraint on the "outer" type parameter:
However, the case where there is constraint on the
:a
itself fails to compile:Something is happening here where it's not "seeing" that in the instance,
:a
is anEq
. I think the problem is with the instance definition, not the typeclass definition, because it correctly doesn't compile without theEq
typeclass either:I tested this in both
main
and the branch in #1315 , getting the same results, so I believe this is independent from #1050. I'm not sure if that PR is the appropriate place to address this - @YarinHeffes.Interestingly, it does work if you define the typeclass over a concrete type that is an Eq. This compiles properly:
From a practical standpoint I don't know if this is a huge deal, but it does keep library designers from preventing silly things like this:
Finally, as a sanity check that this should even be possible, I checked and in Haskell putting
Eq
overa
does work there. (Not that Coalton has to have the same type system as Haskell in all cases, but since this seemed like a bug and not a feature I thought that was a reasonable point of comparison:The text was updated successfully, but these errors were encountered: