Skip to content

Commit febfac4

Browse files
committed
As part of a fix for goldfirere/th-desugar#199 and goldfirere/th-desugar#220, goldfirere/th-desugar#227 improves `th-desugar`'s ability to locally reify and desugar precise types for Haskell98-style data constructors and class methods. This has a couple of knock-on effects for `singletons`: * The type of `dsCon` has changes to accept `DTyVarBndrSpec`s instead of `DTyVarBndrUnit`s, so we must adapt the call sites in `singletons-th` accordingly. * Some of the test cases in `singletons-base` need to have their expected output updated to account for the improved kind information and specificity information flowing down from standalone kind signatures.
1 parent 332c1a0 commit febfac4

File tree

8 files changed

+79
-38
lines changed

8 files changed

+79
-38
lines changed

cabal.project

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ packages: ./singletons
55
source-repository-package
66
type: git
77
location: https://github.com/goldfirere/th-desugar
8-
tag: 75a0731adb32382d281c2eac62dfff2735723334
8+
tag: c7b460412fe9896597270be94a243972833c0a66

singletons-base/tests/compile-and-dump/Promote/T361.golden

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Promote/T361.hs:0:0:: Splicing declarations
22
genDefunSymbols [''Proxy]
33
======>
4-
type ProxySym0 :: forall k (t :: k). Proxy t
5-
type family ProxySym0 @k @(t :: k) :: Proxy t where
4+
type ProxySym0 :: forall {k :: Type} (t :: k). Proxy t
5+
type family ProxySym0 @(t :: k) :: Proxy t where
66
ProxySym0 = 'Proxy
77
Promote/T361.hs:(0,0)-(0,0): Splicing declarations
88
promote

singletons-base/tests/compile-and-dump/Singletons/T353.golden

+16-12
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Singletons/T353.hs:(0,0)-(0,0): Splicing declarations
3333
Singletons/T353.hs:0:0:: Splicing declarations
3434
genDefunSymbols [''Prod]
3535
======>
36-
type MkProdSym0 :: forall k
36+
type MkProdSym0 :: forall {k :: Type}
3737
(f :: k -> Type)
3838
(g :: k -> Type)
3939
(p :: k). (~>) (f p) ((~>) (g p) (Prod f g p))
@@ -44,7 +44,7 @@ Singletons/T353.hs:0:0:: Splicing declarations
4444
type instance Apply @(f p) @((~>) (g p) (Prod f g p)) MkProdSym0 a0123456789876543210 = MkProdSym1 a0123456789876543210
4545
instance SuppressUnusedWarnings MkProdSym0 where
4646
suppressUnusedWarnings = snd ((,) MkProdSym0KindInference ())
47-
type MkProdSym1 :: forall k
47+
type MkProdSym1 :: forall {k :: Type}
4848
(f :: k -> Type)
4949
(g :: k -> Type)
5050
(p :: k). f p -> (~>) (g p) (Prod f g p)
@@ -55,18 +55,18 @@ Singletons/T353.hs:0:0:: Splicing declarations
5555
type instance Apply @(g p) @(Prod f g p) (MkProdSym1 a0123456789876543210) a0123456789876543210 = 'MkProd a0123456789876543210 a0123456789876543210
5656
instance SuppressUnusedWarnings (MkProdSym1 a0123456789876543210) where
5757
suppressUnusedWarnings = snd ((,) MkProdSym1KindInference ())
58-
type MkProdSym2 :: forall k
58+
type MkProdSym2 :: forall {k :: Type}
5959
(f :: k -> Type)
6060
(g :: k -> Type)
6161
(p :: k). f p -> g p -> Prod f g p
62-
type family MkProdSym2 @k @(f :: k -> Type) @(g :: k
63-
-> Type) @(p :: k) (a0123456789876543210 :: f p) (a0123456789876543210 :: g p) :: Prod f g p where
62+
type family MkProdSym2 @(f :: k -> Type) @(g :: k
63+
-> Type) @(p :: k) (a0123456789876543210 :: f p) (a0123456789876543210 :: g p) :: Prod f g p where
6464
MkProdSym2 a0123456789876543210 a0123456789876543210 = 'MkProd a0123456789876543210 a0123456789876543210
6565
Singletons/T353.hs:0:0:: Splicing declarations
6666
genDefunSymbols [''Foo]
6767
======>
68-
type MkFooSym0 :: forall k
69-
k
68+
type MkFooSym0 :: forall {k :: Type}
69+
{k :: Type}
7070
(a :: k)
7171
(b :: k). (~>) (Proxy a) ((~>) (Proxy b) (Foo a b))
7272
data MkFooSym0 :: (~>) (Proxy a) ((~>) (Proxy b) (Foo a b))
@@ -76,16 +76,20 @@ Singletons/T353.hs:0:0:: Splicing declarations
7676
type instance Apply @(Proxy a) @((~>) (Proxy b) (Foo a b)) MkFooSym0 a0123456789876543210 = MkFooSym1 a0123456789876543210
7777
instance SuppressUnusedWarnings MkFooSym0 where
7878
suppressUnusedWarnings = snd ((,) MkFooSym0KindInference ())
79-
type MkFooSym1 :: forall k k (a :: k) (b :: k). Proxy a
80-
-> (~>) (Proxy b) (Foo a b)
79+
type MkFooSym1 :: forall {k :: Type}
80+
{k :: Type}
81+
(a :: k)
82+
(b :: k). Proxy a -> (~>) (Proxy b) (Foo a b)
8183
data MkFooSym1 (a0123456789876543210 :: Proxy a) :: (~>) (Proxy b) (Foo a b)
8284
where
8385
MkFooSym1KindInference :: SameKind (Apply (MkFooSym1 a0123456789876543210) arg) (MkFooSym2 a0123456789876543210 arg) =>
8486
MkFooSym1 a0123456789876543210 a0123456789876543210
8587
type instance Apply @(Proxy b) @(Foo a b) (MkFooSym1 a0123456789876543210) a0123456789876543210 = 'MkFoo a0123456789876543210 a0123456789876543210
8688
instance SuppressUnusedWarnings (MkFooSym1 a0123456789876543210) where
8789
suppressUnusedWarnings = snd ((,) MkFooSym1KindInference ())
88-
type MkFooSym2 :: forall k k (a :: k) (b :: k). Proxy a
89-
-> Proxy b -> Foo a b
90-
type family MkFooSym2 @k @k @(a :: k) @(b :: k) (a0123456789876543210 :: Proxy a) (a0123456789876543210 :: Proxy b) :: Foo a b where
90+
type MkFooSym2 :: forall {k :: Type}
91+
{k :: Type}
92+
(a :: k)
93+
(b :: k). Proxy a -> Proxy b -> Foo a b
94+
type family MkFooSym2 @(a :: k) @(b :: k) (a0123456789876543210 :: Proxy a) (a0123456789876543210 :: Proxy b) :: Foo a b where
9195
MkFooSym2 a0123456789876543210 a0123456789876543210 = 'MkFoo a0123456789876543210 a0123456789876543210

singletons-base/tests/compile-and-dump/Singletons/T567.golden

+12-9
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,32 @@ Singletons/T567.hs:(0,0)-(0,0): Splicing declarations
1919
data D3 x (p :: Proxy x) = MkD3
2020
type D4 :: forall k. forall (a :: k) -> Proxy a -> Type
2121
data D4 (x :: j) (p :: Proxy x) = MkD4
22-
type MkD1Sym0 :: forall x p. D1 x p
23-
type family MkD1Sym0 @x @p :: D1 x p where
22+
type MkD1Sym0 :: forall k (x :: k) (p :: Proxy x). D1 x p
23+
type family MkD1Sym0 @k @(x :: k) @(p :: Proxy x) :: D1 x p where
2424
MkD1Sym0 = MkD1
25-
type MkD2Sym0 :: forall j (x :: j) p. D2 x p
26-
type family MkD2Sym0 @j @(x :: j) @p :: D2 x p where
25+
type MkD2Sym0 :: forall j (x :: j) (p :: Proxy x). D2 x p
26+
type family MkD2Sym0 @j @(x :: j) @(p :: Proxy x) :: D2 x p where
2727
MkD2Sym0 = MkD2
28-
type MkD3Sym0 :: forall x (p :: Proxy x). D3 x p
29-
type family MkD3Sym0 @x @(p :: Proxy x) :: D3 x p where
28+
type MkD3Sym0 :: forall k (x :: k) (p :: Proxy x). D3 x p
29+
type family MkD3Sym0 @k @(x :: k) @(p :: Proxy x) :: D3 x p where
3030
MkD3Sym0 = MkD3
3131
type MkD4Sym0 :: forall j (x :: j) (p :: Proxy x). D4 x p
3232
type family MkD4Sym0 @j @(x :: j) @(p :: Proxy x) :: D4 x p where
3333
MkD4Sym0 = MkD4
3434
type SD1 :: forall k (x :: k) (p :: Proxy x). D1 x p -> Type
3535
data SD1 :: forall k (x :: k) (p :: Proxy x). D1 x p -> Type
36-
where SMkD1 :: forall x p. SD1 (MkD1 :: D1 x p)
36+
where
37+
SMkD1 :: forall k (x :: k) (p :: Proxy x). SD1 (MkD1 :: D1 x p)
3738
type instance Sing @(D1 x p) = SD1
3839
type SD2 :: forall j (x :: j) (p :: Proxy x). D2 x p -> Type
3940
data SD2 :: forall j (x :: j) (p :: Proxy x). D2 x p -> Type
40-
where SMkD2 :: forall j (x :: j) p. SD2 (MkD2 :: D2 x p)
41+
where
42+
SMkD2 :: forall j (x :: j) (p :: Proxy x). SD2 (MkD2 :: D2 x p)
4143
type instance Sing @(D2 x p) = SD2
4244
type SD3 :: forall k (x :: k) (p :: Proxy x). D3 x p -> Type
4345
data SD3 :: forall k (x :: k) (p :: Proxy x). D3 x p -> Type
44-
where SMkD3 :: forall x (p :: Proxy x). SD3 (MkD3 :: D3 x p)
46+
where
47+
SMkD3 :: forall k (x :: k) (p :: Proxy x). SD3 (MkD3 :: D3 x p)
4548
type instance Sing @(D3 x p) = SD3
4649
type SD4 :: forall j (x :: j) (p :: Proxy x). D4 x p -> Type
4750
data SD4 :: forall j (x :: j) (p :: Proxy x). D4 x p -> Type

singletons-base/tests/compile-and-dump/Singletons/TypeAbstractions.golden

+6-4
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,16 @@ Singletons/TypeAbstractions.hs:(0,0)-(0,0): Splicing declarations
157157
-> Proxy b -> D3 @j a @k b
158158
type family MkD3Sym2 @j @(a :: j) @k @(b :: k) (a0123456789876543210 :: Proxy a) (a0123456789876543210 :: Proxy b) :: D3 @j a @k b where
159159
MkD3Sym2 a0123456789876543210 a0123456789876543210 = MkD3 a0123456789876543210 a0123456789876543210
160-
type MkD4Sym0 :: forall a. (~>) a (D4 @a)
160+
type MkD4Sym0 :: forall (a :: Type). (~>) a (D4 @a)
161161
data MkD4Sym0 :: (~>) a (D4 @a)
162162
where
163163
MkD4Sym0KindInference :: SameKind (Apply MkD4Sym0 arg) (MkD4Sym1 arg) =>
164164
MkD4Sym0 a0123456789876543210
165165
type instance Apply @a @(D4 @a) MkD4Sym0 a0123456789876543210 = MkD4 a0123456789876543210
166166
instance SuppressUnusedWarnings MkD4Sym0 where
167167
suppressUnusedWarnings = snd ((,) MkD4Sym0KindInference ())
168-
type MkD4Sym1 :: forall a. a -> D4 @a
169-
type family MkD4Sym1 @a (a0123456789876543210 :: a) :: D4 @a where
168+
type MkD4Sym1 :: forall (a :: Type). a -> D4 @a
169+
type family MkD4Sym1 @(a :: Type) (a0123456789876543210 :: a) :: D4 @a where
170170
MkD4Sym1 a0123456789876543210 = MkD4 a0123456789876543210
171171
type Meth1Sym0 :: forall j
172172
k
@@ -260,7 +260,9 @@ Singletons/TypeAbstractions.hs:(0,0)-(0,0): Splicing declarations
260260
type instance Sing @(D3 @j a @k b) = SD3
261261
type SD4 :: forall (a :: Type). D4 @a -> Type
262262
data SD4 :: forall (a :: Type). D4 @a -> Type
263-
where SMkD4 :: forall a (n :: a). (Sing n) -> SD4 (MkD4 n :: D4 @a)
263+
where
264+
SMkD4 :: forall (a :: Type) (n :: a).
265+
(Sing n) -> SD4 (MkD4 n :: D4 @a)
264266
type instance Sing @(D4 @a) = SD4
265267
class SC1 @j @k (a :: j) (b :: k) where
266268
sMeth1 ::

singletons-th/CHANGES.md

+28
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,34 @@ next [????.??.??]
1616
singled version of `x`.
1717
* Add support for promoting and singling type variables that scope over the
1818
bodies of class method defaults and instance methods.
19+
* `singletons-th` can now generate more precise types for singled data
20+
constructors whose parent data types have standalone kind signatures. For
21+
instance, consider this data type:
22+
23+
```hs
24+
$(singletons [d|
25+
type D :: forall k. k -> Type
26+
data D a = MkD
27+
|])
28+
```
29+
30+
Previously, `singletons-th` would generate the following type for `SMkD` (the
31+
singled counterpart to `MkD`):
32+
33+
```hs
34+
data SD :: forall k. k -> Type where
35+
SMkD :: forall a. SD (MkD :: D a)
36+
```
37+
38+
This was not as precise as it could have been, as the type of `SMkD` did not
39+
make the kind variable `k` eligible for visible type application (as is the
40+
case in `MkD :: forall k (a :: k). D a`). `singletons-th` now accomplishes
41+
this by generating the following code instead:
42+
43+
```hs
44+
data SD :: forall k. k -> Type where
45+
SMkD :: forall k (a :: k). SD (MkD :: D a)
46+
```
1947

2048
3.4 [2024.05.12]
2149
----------------

singletons-th/src/Data/Singletons/TH/Promote.hs

+5-4
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,11 @@ promoteInstance :: OptionsMonad q => DerivDesc q -> String -> Name -> q [Dec]
162162
promoteInstance mk_inst class_name name = do
163163
(df, tvbs, cons) <- getDataD ("I cannot make an instance of " ++ class_name
164164
++ " for it.") name
165-
tvbs' <- mapM dsTvbVis tvbs
166-
let data_ty = foldTypeTvbs (DConT name) tvbs'
167-
cons' <- concatMapM (dsCon tvbs' data_ty) cons
168-
let data_decl = DataDecl df name tvbs' cons'
165+
dtvbs <- mapM dsTvbVis tvbs
166+
let data_ty = foldTypeTvbs (DConT name) dtvbs
167+
dtvbSpecs = changeDTVFlags SpecifiedSpec dtvbs
168+
cons' <- concatMapM (dsCon dtvbSpecs data_ty) cons
169+
let data_decl = DataDecl df name dtvbs cons'
169170
raw_inst <- mk_inst Nothing data_ty data_decl
170171
decs <- promoteM_ [] $ void $
171172
promoteInstanceDec OMap.empty Map.empty raw_inst

singletons-th/src/Data/Singletons/TH/Single.hs

+9-6
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ singDecideInstance :: OptionsMonad q => Name -> q [Dec]
148148
singDecideInstance name = do
149149
(_df, tvbs, cons) <- getDataD ("I cannot make an instance of SDecide for it.") name
150150
dtvbs <- mapM dsTvbVis tvbs
151-
let data_ty = foldTypeTvbs (DConT name) dtvbs
152-
dcons <- concatMapM (dsCon dtvbs data_ty) cons
151+
let data_ty = foldTypeTvbs (DConT name) dtvbs
152+
dtvbSpecs = changeDTVFlags SpecifiedSpec dtvbs
153+
dcons <- concatMapM (dsCon dtvbSpecs data_ty) cons
153154
(scons, _) <- singM [] $ mapM (singCtor name) dcons
154155
sDecideInstance <- mkDecideInstance Nothing data_ty dcons scons
155156
eqInstance <- mkEqInstanceForSingleton data_ty name
@@ -200,8 +201,9 @@ showSingInstance :: OptionsMonad q => Name -> q [Dec]
200201
showSingInstance name = do
201202
(df, tvbs, cons) <- getDataD ("I cannot make an instance of Show for it.") name
202203
dtvbs <- mapM dsTvbVis tvbs
203-
let data_ty = foldTypeTvbs (DConT name) dtvbs
204-
dcons <- concatMapM (dsCon dtvbs data_ty) cons
204+
let data_ty = foldTypeTvbs (DConT name) dtvbs
205+
dtvbSpecs = changeDTVFlags SpecifiedSpec dtvbs
206+
dcons <- concatMapM (dsCon dtvbSpecs data_ty) cons
205207
let tyvars = map (DVarT . extractTvbName) dtvbs
206208
kind = foldType (DConT name) tyvars
207209
data_decl = DataDecl df name dtvbs dcons
@@ -272,8 +274,9 @@ singInstance mk_inst inst_name name = do
272274
(df, tvbs, cons) <- getDataD ("I cannot make an instance of " ++ inst_name
273275
++ " for it.") name
274276
dtvbs <- mapM dsTvbVis tvbs
275-
let data_ty = foldTypeTvbs (DConT name) dtvbs
276-
dcons <- concatMapM (dsCon dtvbs data_ty) cons
277+
let data_ty = foldTypeTvbs (DConT name) dtvbs
278+
dtvbSpecs = changeDTVFlags SpecifiedSpec dtvbs
279+
dcons <- concatMapM (dsCon dtvbSpecs data_ty) cons
277280
let data_decl = DataDecl df name dtvbs dcons
278281
raw_inst <- mk_inst Nothing data_ty data_decl
279282
(a_inst, decs) <- promoteM [] $

0 commit comments

Comments
 (0)