-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Quantify class methods' kind variables in the correct order using Typ…
…eAbstractions When promoting a class with a standalone kind signature, it is possible to ensure that the promoted methods' kind variables are quantified in the same order as the original method's type variables. This is now possible thanks to the `TypeAbstractions` language extension, which lets `singletons-th` pick the exact order of kind variables in the promoted methods' associated type families using `@` binders. For the full details of how this is accomplished, see the expanded `Note [Promoted class methods and kind variable ordering]` in `D.S.TH.Promote` (specifically, `Case 1: Parent class with standalone kind signature`). As it turns out, many of the steps we need to perform to achieve this are the same steps that the `singDataSAK` function performs when producing a standalone kind signature for a singled `data` declaration. As such, I factored out the common bits into a helper function called `matchUpSAKWithDecl` in `D.S.TH.Util`. Fixes #589.
- Loading branch information
1 parent
d8c48c5
commit 0f4bfc3
Showing
13 changed files
with
693 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
singletons-base/tests/compile-and-dump/Singletons/T589.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
Singletons/T589.hs:(0,0)-(0,0): Splicing declarations | ||
singletons | ||
[d| type C1 :: Type -> Constraint | ||
type C2 :: k -> Constraint | ||
|
||
class C1 b where | ||
m1 :: forall a. a -> b -> a | ||
class C2 b where | ||
m2 :: a -> Proxy b | ||
|
||
instance C1 Ordering where | ||
m1 x _ = x | ||
instance C2 Ordering where | ||
m2 _ = Proxy |] | ||
======> | ||
type C1 :: Type -> Constraint | ||
class C1 b where | ||
m1 :: forall a. a -> b -> a | ||
instance C1 Ordering where | ||
m1 x _ = x | ||
type C2 :: k -> Constraint | ||
class C2 b where | ||
m2 :: a -> Proxy b | ||
instance C2 Ordering where | ||
m2 _ = Proxy | ||
type M1Sym0 :: forall (b :: Type) a. (~>) a ((~>) b a) | ||
data M1Sym0 :: (~>) a ((~>) b a) | ||
where | ||
M1Sym0KindInference :: SameKind (Apply M1Sym0 arg) (M1Sym1 arg) => | ||
M1Sym0 a0123456789876543210 | ||
type instance Apply M1Sym0 a0123456789876543210 = M1Sym1 a0123456789876543210 | ||
instance SuppressUnusedWarnings M1Sym0 where | ||
suppressUnusedWarnings = snd ((,) M1Sym0KindInference ()) | ||
type M1Sym1 :: forall (b :: Type) a. a -> (~>) b a | ||
data M1Sym1 (a0123456789876543210 :: a) :: (~>) b a | ||
where | ||
M1Sym1KindInference :: SameKind (Apply (M1Sym1 a0123456789876543210) arg) (M1Sym2 a0123456789876543210 arg) => | ||
M1Sym1 a0123456789876543210 a0123456789876543210 | ||
type instance Apply (M1Sym1 a0123456789876543210) a0123456789876543210 = M1 a0123456789876543210 a0123456789876543210 | ||
instance SuppressUnusedWarnings (M1Sym1 a0123456789876543210) where | ||
suppressUnusedWarnings = snd ((,) M1Sym1KindInference ()) | ||
type M1Sym2 :: forall (b :: Type) a. a -> b -> a | ||
type family M1Sym2 @(b :: Type) @a (a0123456789876543210 :: a) (a0123456789876543210 :: b) :: a where | ||
M1Sym2 a0123456789876543210 a0123456789876543210 = M1 a0123456789876543210 a0123456789876543210 | ||
type PC1 :: Type -> Constraint | ||
class PC1 (b :: Type) where | ||
type family M1 @(b :: Type) @a (arg :: a) (arg :: b) :: a | ||
type M2Sym0 :: forall k (b :: k) a. (~>) a (Proxy b) | ||
data M2Sym0 :: (~>) a (Proxy b) | ||
where | ||
M2Sym0KindInference :: SameKind (Apply M2Sym0 arg) (M2Sym1 arg) => | ||
M2Sym0 a0123456789876543210 | ||
type instance Apply M2Sym0 a0123456789876543210 = M2 a0123456789876543210 | ||
instance SuppressUnusedWarnings M2Sym0 where | ||
suppressUnusedWarnings = snd ((,) M2Sym0KindInference ()) | ||
type M2Sym1 :: forall k (b :: k) a. a -> Proxy b | ||
type family M2Sym1 @k @(b :: k) @a (a0123456789876543210 :: a) :: Proxy b where | ||
M2Sym1 a0123456789876543210 = M2 a0123456789876543210 | ||
type PC2 :: k -> Constraint | ||
class PC2 @k (b :: k) where | ||
type family M2 @k @(b :: k) @a (arg :: a) :: Proxy b | ||
type M1_0123456789876543210 :: forall a. a -> Ordering -> a | ||
type family M1_0123456789876543210 @a (a :: a) (a :: Ordering) :: a where | ||
M1_0123456789876543210 @a x _ = x | ||
type M1_0123456789876543210Sym0 :: forall a. (~>) a ((~>) Ordering a) | ||
data M1_0123456789876543210Sym0 :: (~>) a ((~>) Ordering a) | ||
where | ||
M1_0123456789876543210Sym0KindInference :: SameKind (Apply M1_0123456789876543210Sym0 arg) (M1_0123456789876543210Sym1 arg) => | ||
M1_0123456789876543210Sym0 a0123456789876543210 | ||
type instance Apply M1_0123456789876543210Sym0 a0123456789876543210 = M1_0123456789876543210Sym1 a0123456789876543210 | ||
instance SuppressUnusedWarnings M1_0123456789876543210Sym0 where | ||
suppressUnusedWarnings | ||
= snd ((,) M1_0123456789876543210Sym0KindInference ()) | ||
type M1_0123456789876543210Sym1 :: forall a. a -> (~>) Ordering a | ||
data M1_0123456789876543210Sym1 (a0123456789876543210 :: a) :: (~>) Ordering a | ||
where | ||
M1_0123456789876543210Sym1KindInference :: SameKind (Apply (M1_0123456789876543210Sym1 a0123456789876543210) arg) (M1_0123456789876543210Sym2 a0123456789876543210 arg) => | ||
M1_0123456789876543210Sym1 a0123456789876543210 a0123456789876543210 | ||
type instance Apply (M1_0123456789876543210Sym1 a0123456789876543210) a0123456789876543210 = M1_0123456789876543210 a0123456789876543210 a0123456789876543210 | ||
instance SuppressUnusedWarnings (M1_0123456789876543210Sym1 a0123456789876543210) where | ||
suppressUnusedWarnings | ||
= snd ((,) M1_0123456789876543210Sym1KindInference ()) | ||
type M1_0123456789876543210Sym2 :: forall a. a -> Ordering -> a | ||
type family M1_0123456789876543210Sym2 @a (a0123456789876543210 :: a) (a0123456789876543210 :: Ordering) :: a where | ||
M1_0123456789876543210Sym2 a0123456789876543210 a0123456789876543210 = M1_0123456789876543210 a0123456789876543210 a0123456789876543210 | ||
instance PC1 Ordering where | ||
type M1 a a = Apply (Apply M1_0123456789876543210Sym0 a) a | ||
type M2_0123456789876543210 :: forall a. a -> Proxy Ordering | ||
type family M2_0123456789876543210 @a (a :: a) :: Proxy Ordering where | ||
M2_0123456789876543210 @a _ = ProxySym0 | ||
type M2_0123456789876543210Sym0 :: forall a. (~>) a (Proxy Ordering) | ||
data M2_0123456789876543210Sym0 :: (~>) a (Proxy Ordering) | ||
where | ||
M2_0123456789876543210Sym0KindInference :: SameKind (Apply M2_0123456789876543210Sym0 arg) (M2_0123456789876543210Sym1 arg) => | ||
M2_0123456789876543210Sym0 a0123456789876543210 | ||
type instance Apply M2_0123456789876543210Sym0 a0123456789876543210 = M2_0123456789876543210 a0123456789876543210 | ||
instance SuppressUnusedWarnings M2_0123456789876543210Sym0 where | ||
suppressUnusedWarnings | ||
= snd ((,) M2_0123456789876543210Sym0KindInference ()) | ||
type M2_0123456789876543210Sym1 :: forall a. a -> Proxy Ordering | ||
type family M2_0123456789876543210Sym1 @a (a0123456789876543210 :: a) :: Proxy Ordering where | ||
M2_0123456789876543210Sym1 a0123456789876543210 = M2_0123456789876543210 a0123456789876543210 | ||
instance PC2 Ordering where | ||
type M2 a = Apply M2_0123456789876543210Sym0 a | ||
class SC1 b where | ||
sM1 :: | ||
forall a (t :: a) (t :: b). Sing t | ||
-> Sing t -> Sing (Apply (Apply M1Sym0 t) t :: a) | ||
class SC2 b where | ||
sM2 :: | ||
(forall (t :: a). | ||
Sing t -> Sing (Apply M2Sym0 t :: Proxy b) :: Type) | ||
instance SC1 Ordering where | ||
sM1 (sX :: Sing x) _ = sX | ||
instance SC2 Ordering where | ||
sM2 _ = SProxy | ||
type SC1 :: Type -> Constraint | ||
instance SC1 b => SingI (M1Sym0 :: (~>) a ((~>) b a)) where | ||
sing = singFun2 @M1Sym0 sM1 | ||
instance (SC1 b, SingI d) => | ||
SingI (M1Sym1 (d :: a) :: (~>) b a) where | ||
sing = singFun1 @(M1Sym1 (d :: a)) (sM1 (sing @d)) | ||
instance SC1 b => SingI1 (M1Sym1 :: a -> (~>) b a) where | ||
liftSing (s :: Sing (d :: a)) = singFun1 @(M1Sym1 (d :: a)) (sM1 s) | ||
type SC2 :: k -> Constraint | ||
instance SC2 b => SingI (M2Sym0 :: (~>) a (Proxy b)) where | ||
sing = singFun1 @M2Sym0 sM2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
module T589 where | ||
|
||
import Data.Kind | ||
import Data.Proxy | ||
import Data.Proxy.Singletons | ||
import Data.Singletons.Base.TH | ||
import Prelude.Singletons | ||
|
||
$(singletons [d| | ||
type C1 :: Type -> Constraint | ||
class C1 b where | ||
m1 :: forall a. a -> b -> a | ||
|
||
instance C1 Ordering where | ||
m1 x _ = x | ||
|
||
type C2 :: k -> Constraint | ||
class C2 b where | ||
m2 :: a -> Proxy b | ||
|
||
instance C2 Ordering where | ||
m2 _ = Proxy | ||
|]) | ||
|
||
-- Test some type variable orderings | ||
m1Ex :: Bool -> Ordering -> Bool | ||
m1Ex = m1 @Ordering @Bool | ||
|
||
type M1Ex :: Bool | ||
type M1Ex = M1 @Ordering @Bool True EQ | ||
|
||
type M1Ex0 :: Bool ~> Ordering ~> Bool | ||
type M1Ex0 = M1Sym0 @Ordering @Bool | ||
|
||
type M1Ex1 :: Bool -> Ordering ~> Bool | ||
type M1Ex1 = M1Sym1 @Ordering @Bool | ||
|
||
type M1Ex2 :: Bool | ||
type M1Ex2 = M1Sym2 @Ordering @Bool True EQ | ||
|
||
sM1Ex :: forall (x :: Bool) (y :: Ordering). | ||
Sing x -> Sing y -> Sing (M1 @Ordering @Bool x y) | ||
sM1Ex = sM1 @Ordering @Bool | ||
|
||
m2Ex :: Bool -> Proxy Ordering | ||
m2Ex = m2 @Type @Ordering @Bool | ||
|
||
type M2Ex :: Proxy Ordering | ||
type M2Ex = M2 @Type @Ordering @Bool True | ||
|
||
type M2Ex0 :: Bool ~> Proxy Ordering | ||
type M2Ex0 = M2Sym0 @Type @Ordering @Bool | ||
|
||
type M2Ex1 :: Proxy Ordering | ||
type M2Ex1 = M2Sym1 @Type @Ordering @Bool True | ||
|
||
sM2Ex :: forall (x :: Bool). | ||
Sing x -> Sing (M2 @Type @Ordering @Bool x) | ||
sM2Ex = sM2 @Type @Ordering @Bool |
Oops, something went wrong.