-
Notifications
You must be signed in to change notification settings - Fork 15
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
Handling of type families is inconsistent with GHC behaviour #21
Comments
I agree that this is a bug, but don't know yet when I'll have time to fix it. |
@christiaanb I need it urgently, so if you can point me in the right direction, I can start working on it. |
@madgen Could you provide a small test case? I was trying to reproduce what you're saying, but the following compiles fine: {-# LANGUAGE TypeOperators, DataKinds, GADTs, KindSignatures, TypeFamilies,
AllowAmbiguousTypes, ScopedTypeVariables, TypeApplications #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}
import GHC.TypeLits
type family T (a :: Nat) :: Nat
f :: forall b a c . b <= T a + b => c
f = undefined
g :: forall (a :: Nat) c . c
g = f @0 @a @c I guess I'm misunderstanding the exact issue that you're having |
It is so bizarre. When I take it out of the context it occurred, the problem goes way. I still get |
@madgen ah... so let's say we have: type family T (a :: Nat) :: Nat
type family G (a :: Nat) :: Nat is the following then vacuously true?
i.e., must the type checker plugin discharge it? Well... it cannot, because we're dealing with natural numbers. Let's say we add the following instances:
then instantiating:
reduces to:
which gets stuck in GHC, even without the plugin: {-# LANGUAGE TypeOperators, DataKinds, GADTs, KindSignatures, TypeFamilies,
AllowAmbiguousTypes, ScopedTypeVariables, TypeApplications,
UndecidableInstances #-}
import GHC.TypeLits
type family T (a :: Nat) :: Nat
type instance T a = a
type family G (a :: Nat) :: Nat
type instance G a = a - 4
f :: b <= T a + b => c
f = undefined
g :: forall (a :: Nat) (b :: Nat) c . c
g = f @(G 2) @3 @c with:
|
@christiaanb I'm a bit confused now, I'm clearly confusing semantics of something. |
Or |
Fair. In my case both type families are non-negative, do you think I can convey this information to the type checker/plugin in a useful manner? |
I guess we could make a class:
And add instances for your type families if you want to assert that: it reduces for any input. Then the plugin could look up instances for this But even then.... what if you type family is applied to |
Well, so going back to my original post, GHC is happy to type check the following: {-# LANGUAGE TypeOperators, DataKinds, GADTs, KindSignatures, TypeFamilies,
AllowAmbiguousTypes, ScopedTypeVariables, TypeApplications,
UndecidableInstances #-}
import GHC.TypeLits
type family G (a :: Nat) :: Nat
type instance G a = a - 4
f' :: 0 <= a => c
f' = undefined
g' :: forall (a :: Nat) (b :: Nat) c . c
g' = f' @(G 2) @c So, it is already unsound which irks me as well, but if GHC (and consequently your plugin) will do that, I might as well rip its benefits. Does that make sense? |
I'll add a flag to the plugin by which you can assert that all constants, i.e. |
Wow, awesome. I didn't see this going as smoothly as it did. It's a great project by the way. Thank you for making it. Let me know if there are interesting things to do. I'd be interested in helping. |
I've pushed a commit which adds the flag: 45080a9 With regards to interesting things to do: I would like to extend then inequality solver so that it can handle the expressions in: clash-lang/ghc-typelits-extra#15 |
Hi,
This is kind of related to #7, but emphasises a different point.
So if we have
we get a type error and the comment on #7 suggests that is to be cautious about type families that may produce type errors. So I agree with that but GHC doesn't.
As GHC
<=
does not inspect the right-hand side a constraint of the form0 <= T a
, always type checks. We might argue that this is the wrong behaviour, but that's what GHC does, so perhaps it is not too bad to be consistent with it?Would you consider a more relaxed approach to handling of stuck type families?
The text was updated successfully, but these errors were encountered: