-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathCore.hs
2078 lines (1869 loc) · 83.3 KB
/
Core.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{- Language/Haskell/TH/Desugar/Core.hs
(c) Richard Eisenberg 2013
rae@cs.brynmawr.edu
Desugars full Template Haskell syntax into a smaller core syntax for further
processing. The desugared types and constructors are prefixed with a D.
-}
{-# LANGUAGE TemplateHaskellQuotes, LambdaCase, CPP, ScopedTypeVariables,
TupleSections, DeriveDataTypeable, DeriveGeneric #-}
module Language.Haskell.TH.Desugar.Core where
import Prelude hiding (mapM, foldl, foldr, all, elem, exp, concatMap, and)
import Language.Haskell.TH hiding (Extension(..), match, clause, cxt)
import Language.Haskell.TH.Datatype.TyVarBndr
import Language.Haskell.TH.Syntax hiding (Extension(..), lift)
import Control.Monad hiding (forM_, mapM)
import qualified Control.Monad.Fail as Fail
import Control.Monad.Trans (MonadTrans(..))
import Control.Monad.Writer (MonadWriter(..), WriterT(..))
import Control.Monad.Zip
import Data.Data (Data)
import Data.Either (lefts)
import Data.Foldable as F hiding (concat, notElem)
import Data.Function (on)
import qualified Data.List as L
import qualified Data.Map as M
import Data.Map (Map)
import Data.Maybe (isJust, mapMaybe)
import Data.Monoid (All(..))
import qualified Data.Set as S
import Data.Set (Set)
import Data.Traversable
#if __GLASGOW_HASKELL__ >= 803
import GHC.OverloadedLabels ( fromLabel )
#endif
#if __GLASGOW_HASKELL__ >= 807
import GHC.Classes (IP(..))
#else
import qualified Language.Haskell.TH as LangExt (Extension(..))
#endif
#if __GLASGOW_HASKELL__ >= 902
import Data.List.NonEmpty (NonEmpty(..))
import GHC.Records (HasField(..))
#endif
import GHC.Exts
import GHC.Generics (Generic)
import Language.Haskell.TH.Desugar.AST
import Language.Haskell.TH.Desugar.FV
import qualified Language.Haskell.TH.Desugar.OSet as OS
import Language.Haskell.TH.Desugar.OSet (OSet)
import Language.Haskell.TH.Desugar.Util
import Language.Haskell.TH.Desugar.Reify
-- | Desugar an expression
dsExp :: DsMonad q => Exp -> q DExp
dsExp (VarE n) = return $ DVarE n
dsExp (ConE n) = return $ DConE n
dsExp (LitE lit) = return $ DLitE lit
dsExp (AppE e1 e2) = DAppE <$> dsExp e1 <*> dsExp e2
dsExp (InfixE Nothing op Nothing) = dsExp op
dsExp (InfixE (Just lhs) op Nothing) = DAppE <$> (dsExp op) <*> (dsExp lhs)
dsExp (InfixE Nothing op (Just rhs)) = do
lhsName <- newUniqueName "lhs"
op' <- dsExp op
rhs' <- dsExp rhs
return $ DLamE [lhsName] (foldl DAppE op' [DVarE lhsName, rhs'])
dsExp (InfixE (Just lhs) op (Just rhs)) =
DAppE <$> (DAppE <$> dsExp op <*> dsExp lhs) <*> dsExp rhs
dsExp (UInfixE _ _ _) =
fail "Cannot desugar unresolved infix operators."
dsExp (ParensE exp) = dsExp exp
dsExp (LamE pats exp) = do
exp' <- dsExp exp
(pats', exp'') <- dsPatsOverExp pats exp'
mkDLamEFromDPats pats' exp''
dsExp (LamCaseE matches) = do
x <- newUniqueName "x"
matches' <- dsMatches x matches
return $ DLamE [x] (DCaseE (DVarE x) matches')
dsExp (TupE exps) = dsTup tupleDataName exps
dsExp (UnboxedTupE exps) = dsTup unboxedTupleDataName exps
dsExp (CondE e1 e2 e3) =
dsExp (CaseE e1 [mkBoolMatch 'True e2, mkBoolMatch 'False e3])
where
mkBoolMatch :: Name -> Exp -> Match
mkBoolMatch boolDataCon rhs =
Match (ConP boolDataCon
#if __GLASGOW_HASKELL__ >= 901
[]
#endif
[]) (NormalB rhs) []
dsExp (MultiIfE guarded_exps) =
let failure = mkErrorMatchExpr MultiWayIfAlt in
dsGuards guarded_exps failure
dsExp (LetE decs exp) = do
(decs', ip_binder) <- dsLetDecs decs
exp' <- dsExp exp
return $ DLetE decs' $ ip_binder exp'
-- the following special case avoids creating a new "let" when it's not
-- necessary. See #34.
dsExp (CaseE (VarE scrutinee) matches) = do
matches' <- dsMatches scrutinee matches
return $ DCaseE (DVarE scrutinee) matches'
dsExp (CaseE exp matches) = do
scrutinee <- newUniqueName "scrutinee"
exp' <- dsExp exp
matches' <- dsMatches scrutinee matches
return $ DLetE [DValD (DVarP scrutinee) exp'] $
DCaseE (DVarE scrutinee) matches'
#if __GLASGOW_HASKELL__ >= 900
dsExp (DoE mb_mod stmts) = dsDoStmts mb_mod stmts
#else
dsExp (DoE stmts) = dsDoStmts Nothing stmts
#endif
dsExp (CompE stmts) = dsComp stmts
dsExp (ArithSeqE (FromR exp)) = DAppE (DVarE 'enumFrom) <$> dsExp exp
dsExp (ArithSeqE (FromThenR exp1 exp2)) =
DAppE <$> (DAppE (DVarE 'enumFromThen) <$> dsExp exp1) <*> dsExp exp2
dsExp (ArithSeqE (FromToR exp1 exp2)) =
DAppE <$> (DAppE (DVarE 'enumFromTo) <$> dsExp exp1) <*> dsExp exp2
dsExp (ArithSeqE (FromThenToR e1 e2 e3)) =
DAppE <$> (DAppE <$> (DAppE (DVarE 'enumFromThenTo) <$> dsExp e1) <*>
dsExp e2) <*>
dsExp e3
dsExp (ListE exps) = go exps
where go [] = return $ DConE '[]
go (h : t) = DAppE <$> (DAppE (DConE '(:)) <$> dsExp h) <*> go t
dsExp (SigE exp ty) = DSigE <$> dsExp exp <*> dsType ty
dsExp (RecConE con_name field_exps) = do
con <- dataConNameToCon con_name
reordered <- reorder con
return $ foldl DAppE (DConE con_name) reordered
where
reorder con = case con of
NormalC _name fields -> non_record fields
InfixC field1 _name field2 -> non_record [field1, field2]
RecC _name fields -> reorder_fields fields
ForallC _ _ c -> reorder c
GadtC _names fields _ret_ty -> non_record fields
RecGadtC _names fields _ret_ty -> reorder_fields fields
reorder_fields fields = reorderFields con_name fields field_exps
(repeat $ DVarE 'undefined)
non_record fields | null field_exps
-- Special case: record construction is allowed for any
-- constructor, regardless of whether the constructor
-- actually was declared with records, provided that no
-- records are given in the expression itself. (See #59).
--
-- Con{} desugars down to Con undefined ... undefined.
= return $ replicate (length fields) $ DVarE 'undefined
| otherwise =
impossible $ "Record syntax used with non-record constructor "
++ (show con_name) ++ "."
dsExp (RecUpdE exp field_exps) = do
-- here, we need to use one of the field names to find the tycon, somewhat dodgily
first_name <- case field_exps of
((name, _) : _) -> return name
_ -> impossible "Record update with no fields listed."
info <- reifyWithLocals first_name
applied_type <- case info of
VarI _name ty _m_dec -> extract_first_arg ty
_ -> impossible "Record update with an invalid field name."
type_name <- extract_type_name applied_type
(_, _, cons) <- getDataD "This seems to be an error in GHC." type_name
let filtered_cons = filter_cons_with_names cons (map fst field_exps)
exp' <- dsExp exp
matches <- mapM con_to_dmatch filtered_cons
let all_matches
| length filtered_cons == length cons = matches
| otherwise = matches ++ [error_match]
return $ DCaseE exp' all_matches
where
extract_first_arg :: DsMonad q => Type -> q Type
extract_first_arg (AppT (AppT ArrowT arg) _) = return arg
extract_first_arg (ForallT _ _ t) = extract_first_arg t
extract_first_arg (SigT t _) = extract_first_arg t
extract_first_arg _ = impossible "Record selector not a function."
extract_type_name :: DsMonad q => Type -> q Name
extract_type_name (AppT t1 _) = extract_type_name t1
extract_type_name (SigT t _) = extract_type_name t
extract_type_name (ConT n) = return n
extract_type_name _ = impossible "Record selector domain not a datatype."
filter_cons_with_names cons field_names =
filter has_names cons
where
args_contain_names args =
let con_field_names = map fst_of_3 args in
all (`elem` con_field_names) field_names
has_names (RecC _con_name args) =
args_contain_names args
has_names (RecGadtC _con_name args _ret_ty) =
args_contain_names args
has_names (ForallC _ _ c) = has_names c
has_names _ = False
rec_con_to_dmatch con_name args = do
let con_field_names = map fst_of_3 args
field_var_names <- mapM (newUniqueName . nameBase) con_field_names
DMatch (DConP con_name [] (map DVarP field_var_names)) <$>
(foldl DAppE (DConE con_name) <$>
(reorderFields con_name args field_exps (map DVarE field_var_names)))
con_to_dmatch :: DsMonad q => Con -> q DMatch
con_to_dmatch (RecC con_name args) = rec_con_to_dmatch con_name args
-- We're assuming the GADT constructor has only one Name here, but since
-- this constructor was reified, this assumption should always hold true.
con_to_dmatch (RecGadtC [con_name] args _ret_ty) = rec_con_to_dmatch con_name args
con_to_dmatch (ForallC _ _ c) = con_to_dmatch c
con_to_dmatch _ = impossible "Internal error within th-desugar."
error_match = DMatch DWildP (mkErrorMatchExpr RecUpd)
fst_of_3 (x, _, _) = x
dsExp (StaticE exp) = DStaticE <$> dsExp exp
dsExp (UnboundVarE n) = return (DVarE n)
#if __GLASGOW_HASKELL__ >= 801
dsExp (AppTypeE exp ty) = DAppTypeE <$> dsExp exp <*> dsType ty
dsExp (UnboxedSumE exp alt arity) =
DAppE (DConE $ unboxedSumDataName alt arity) <$> dsExp exp
#endif
#if __GLASGOW_HASKELL__ >= 803
dsExp (LabelE str) = return $ DVarE 'fromLabel `DAppTypeE` DLitT (StrTyLit str)
#endif
#if __GLASGOW_HASKELL__ >= 807
dsExp (ImplicitParamVarE n) = return $ DVarE 'ip `DAppTypeE` DLitT (StrTyLit n)
dsExp (MDoE {}) = fail "th-desugar currently does not support RecursiveDo"
#endif
#if __GLASGOW_HASKELL__ >= 902
dsExp (GetFieldE arg field) = DAppE (mkGetFieldProj field) <$> dsExp arg
dsExp (ProjectionE fields) =
case fields of
f :| fs -> return $ foldl' comp (mkGetFieldProj f) fs
where
comp :: DExp -> String -> DExp
comp acc f = DVarE '(.) `DAppE` mkGetFieldProj f `DAppE` acc
#endif
#if __GLASGOW_HASKELL__ >= 903
dsExp (LamCasesE clauses) = do
clauses' <- dsClauses CaseAlt clauses
numArgs <-
case clauses' of
(DClause pats _:_) -> return $ length pats
[] -> fail "\\cases expression must have at least one alternative"
args <- replicateM numArgs (newUniqueName "x")
return $ DLamE args $ DCaseE (mkUnboxedTupleDExp (map DVarE args))
(map dClauseToUnboxedTupleMatch clauses')
#endif
#if __GLASGOW_HASKELL__ >= 907
dsExp (TypedBracketE exp) = DTypedBracketE <$> dsExp exp
dsExp (TypedSpliceE exp) = DTypedSpliceE <$> dsExp exp
#endif
#if __GLASGOW_HASKELL__ >= 909
dsExp (TypeE ty) = DTypeE <$> dsType ty
#endif
-- | Convert a 'DClause' to a 'DMatch' by bundling all of the clause's patterns
-- into a match on a single unboxed tuple pattern. That is, convert this:
--
-- @
-- f x y z = rhs
-- @
--
-- To this:
--
-- @
-- f (# x, y, z #) = rhs
-- @
--
-- This is used to desugar @\\cases@ expressions into lambda expressions.
dClauseToUnboxedTupleMatch :: DClause -> DMatch
dClauseToUnboxedTupleMatch (DClause pats rhs) =
DMatch (mkUnboxedTupleDPat pats) rhs
#if __GLASGOW_HASKELL__ >= 809
dsTup :: DsMonad q => (Int -> Name) -> [Maybe Exp] -> q DExp
dsTup = ds_tup
#else
dsTup :: DsMonad q => (Int -> Name) -> [Exp] -> q DExp
dsTup tuple_data_name = ds_tup tuple_data_name . map Just
#endif
-- | Desugar a tuple (or tuple section) expression.
ds_tup :: forall q. DsMonad q
=> (Int -> Name) -- ^ Compute the 'Name' of a tuple (boxed or unboxed)
-- data constructor from its arity.
-> [Maybe Exp] -- ^ The tuple's subexpressions. 'Nothing' entries
-- denote empty fields in a tuple section.
-> q DExp
ds_tup tuple_data_name mb_exps = do
section_exps <- mapM ds_section_exp mb_exps
let section_vars = lefts section_exps
tup_body = mk_tup_body section_exps
if null section_vars
then return tup_body -- If this isn't a tuple section,
-- don't create a lambda.
else mkDLamEFromDPats (map DVarP section_vars) tup_body
where
-- If dealing with an empty field in a tuple section (Nothing), create a
-- unique name and return Left. These names will be used to construct the
-- lambda expression that it desugars to.
-- (For example, `(,5)` desugars to `\ts -> (,) ts 5`.)
--
-- If dealing with a tuple subexpression (Just), desugar it and return
-- Right.
ds_section_exp :: Maybe Exp -> q (Either Name DExp)
ds_section_exp = maybe (Left <$> qNewName "ts") (fmap Right . dsExp)
mk_tup_body :: [Either Name DExp] -> DExp
mk_tup_body section_exps =
foldl' apply_tup_body (DConE $ tuple_data_name (length section_exps))
section_exps
apply_tup_body :: DExp -> Either Name DExp -> DExp
apply_tup_body f (Left n) = f `DAppE` DVarE n
apply_tup_body f (Right e) = f `DAppE` e
-- | Convert a list of 'DPat' arguments and a 'DExp' body into a 'DLamE'. This
-- is needed since 'DLamE' takes a list of 'Name's for its bound variables
-- instead of 'DPat's, so some reorganization is needed.
mkDLamEFromDPats :: Quasi q => [DPat] -> DExp -> q DExp
mkDLamEFromDPats pats exp
| Just names <- mapM stripDVarP_maybe pats
= return $ DLamE names exp
| otherwise
= do arg_names <- replicateM (length pats) (newUniqueName "arg")
let scrutinee = mkUnboxedTupleDExp (map DVarE arg_names)
match = DMatch (mkUnboxedTupleDPat pats) exp
return $ DLamE arg_names (DCaseE scrutinee [match])
where
stripDVarP_maybe :: DPat -> Maybe Name
stripDVarP_maybe (DVarP n) = Just n
stripDVarP_maybe _ = Nothing
#if __GLASGOW_HASKELL__ >= 902
mkGetFieldProj :: String -> DExp
mkGetFieldProj field = DVarE 'getField `DAppTypeE` DLitT (StrTyLit field)
#endif
-- | Desugar a list of matches for a @case@ statement
dsMatches :: DsMonad q
=> Name -- ^ Name of the scrutinee, which must be a bare var
-> [Match] -- ^ Matches of the @case@ statement
-> q [DMatch]
dsMatches scr = go
where
go :: DsMonad q => [Match] -> q [DMatch]
go [] = return []
go (Match pat body where_decs : rest) = do
rest' <- go rest
let failure = maybeDCaseE CaseAlt (DVarE scr) rest'
exp' <- dsBody body where_decs failure
(pat', exp'') <- dsPatOverExp pat exp'
uni_pattern <- isUniversalPattern pat' -- incomplete attempt at #6
if uni_pattern
then return [DMatch pat' exp'']
else return (DMatch pat' exp'' : rest')
-- | Desugar a @Body@
dsBody :: DsMonad q
=> Body -- ^ body to desugar
-> [Dec] -- ^ "where" declarations
-> DExp -- ^ what to do if the guards don't match
-> q DExp
dsBody (NormalB exp) decs _ = do
(decs', ip_binder) <- dsLetDecs decs
exp' <- dsExp exp
return $ maybeDLetE decs' $ ip_binder exp'
dsBody (GuardedB guarded_exps) decs failure = do
(decs', ip_binder) <- dsLetDecs decs
guarded_exp' <- dsGuards guarded_exps failure
return $ maybeDLetE decs' $ ip_binder guarded_exp'
-- | If decs is non-empty, delcare them in a let:
maybeDLetE :: [DLetDec] -> DExp -> DExp
maybeDLetE [] exp = exp
maybeDLetE decs exp = DLetE decs exp
-- | If matches is non-empty, make a case statement; otherwise make an error statement
maybeDCaseE :: MatchContext -> DExp -> [DMatch] -> DExp
maybeDCaseE mc _ [] = mkErrorMatchExpr mc
maybeDCaseE _ scrut matches = DCaseE scrut matches
-- | Desugar guarded expressions
dsGuards :: DsMonad q
=> [(Guard, Exp)] -- ^ Guarded expressions
-> DExp -- ^ What to do if none of the guards match
-> q DExp
dsGuards [] thing_inside = return thing_inside
dsGuards ((NormalG gd, exp) : rest) thing_inside =
dsGuards ((PatG [NoBindS gd], exp) : rest) thing_inside
dsGuards ((PatG stmts, exp) : rest) thing_inside = do
success <- dsExp exp
failure <- dsGuards rest thing_inside
dsGuardStmts stmts success failure
-- | Desugar the @Stmt@s in a guard
dsGuardStmts :: DsMonad q
=> [Stmt] -- ^ The @Stmt@s to desugar
-> DExp -- ^ What to do if the @Stmt@s yield success
-> DExp -- ^ What to do if the @Stmt@s yield failure
-> q DExp
dsGuardStmts [] success _failure = return success
dsGuardStmts (BindS pat exp : rest) success failure = do
success' <- dsGuardStmts rest success failure
(pat', success'') <- dsPatOverExp pat success'
exp' <- dsExp exp
return $ DCaseE exp' [DMatch pat' success'', DMatch DWildP failure]
dsGuardStmts (LetS decs : rest) success failure = do
(decs', ip_binder) <- dsLetDecs decs
success' <- dsGuardStmts rest success failure
return $ DLetE decs' $ ip_binder success'
-- special-case a final pattern containing "otherwise" or "True"
-- note that GHC does this special-casing, too, in DsGRHSs.isTrueLHsExpr
dsGuardStmts [NoBindS exp] success _failure
| VarE name <- exp
, name == 'otherwise
= return success
| ConE name <- exp
, name == 'True
= return success
dsGuardStmts (NoBindS exp : rest) success failure = do
exp' <- dsExp exp
success' <- dsGuardStmts rest success failure
return $ DCaseE exp' [ DMatch (DConP 'True [] []) success'
, DMatch (DConP 'False [] []) failure ]
dsGuardStmts (ParS _ : _) _ _ = impossible "Parallel comprehension in a pattern guard."
#if __GLASGOW_HASKELL__ >= 807
dsGuardStmts (RecS {} : _) _ _ = fail "th-desugar currently does not support RecursiveDo"
#endif
-- | Desugar the @Stmt@s in a @do@ expression
dsDoStmts :: forall q. DsMonad q => Maybe ModName -> [Stmt] -> q DExp
dsDoStmts mb_mod = go
where
go :: [Stmt] -> q DExp
go [] = impossible "do-expression ended with something other than bare statement."
go [NoBindS exp] = dsExp exp
go (BindS pat exp : rest) = do
rest' <- go rest
dsBindS mb_mod exp pat rest' "do expression"
go (LetS decs : rest) = do
(decs', ip_binder) <- dsLetDecs decs
rest' <- go rest
return $ DLetE decs' $ ip_binder rest'
go (NoBindS exp : rest) = do
exp' <- dsExp exp
rest' <- go rest
let sequence_name = mk_qual_do_name mb_mod '(>>)
return $ DAppE (DAppE (DVarE sequence_name) exp') rest'
go (ParS _ : _) = impossible "Parallel comprehension in a do-statement."
#if __GLASGOW_HASKELL__ >= 807
go (RecS {} : _) = fail "th-desugar currently does not support RecursiveDo"
#endif
-- | Desugar the @Stmt@s in a list or monad comprehension
dsComp :: DsMonad q => [Stmt] -> q DExp
dsComp [] = impossible "List/monad comprehension ended with something other than a bare statement."
dsComp [NoBindS exp] = DAppE (DVarE 'return) <$> dsExp exp
dsComp (BindS pat exp : rest) = do
rest' <- dsComp rest
dsBindS Nothing exp pat rest' "monad comprehension"
dsComp (LetS decs : rest) = do
(decs', ip_binder) <- dsLetDecs decs
rest' <- dsComp rest
return $ DLetE decs' $ ip_binder rest'
dsComp (NoBindS exp : rest) = do
exp' <- dsExp exp
rest' <- dsComp rest
return $ DAppE (DAppE (DVarE '(>>)) (DAppE (DVarE 'guard) exp')) rest'
dsComp (ParS stmtss : rest) = do
(pat, exp) <- dsParComp stmtss
rest' <- dsComp rest
DAppE (DAppE (DVarE '(>>=)) exp) <$> mkDLamEFromDPats [pat] rest'
#if __GLASGOW_HASKELL__ >= 807
dsComp (RecS {} : _) = fail "th-desugar currently does not support RecursiveDo"
#endif
-- Desugar a binding statement in a do- or list comprehension.
--
-- In the event that the pattern in the statement is partial, the desugared
-- case expression will contain a catch-all case that calls 'fail' from either
-- 'MonadFail' or 'Monad', depending on whether the @MonadFailDesugaring@
-- language extension is enabled or not. (On GHCs older than 8.0, 'fail' from
-- 'Monad' is always used.)
dsBindS :: forall q. DsMonad q
=> Maybe ModName -> Exp -> Pat -> DExp -> String -> q DExp
dsBindS mb_mod bind_arg_exp success_pat success_exp ctxt = do
bind_arg_exp' <- dsExp bind_arg_exp
(success_pat', success_exp') <- dsPatOverExp success_pat success_exp
is_univ_pat <- isUniversalPattern success_pat'
let bind_into = DAppE (DAppE (DVarE bind_name) bind_arg_exp')
if is_univ_pat
then bind_into <$> mkDLamEFromDPats [success_pat'] success_exp'
else do arg_name <- newUniqueName "arg"
fail_name <- mk_fail_name
return $ bind_into $ DLamE [arg_name] $ DCaseE (DVarE arg_name)
[ DMatch success_pat' success_exp'
, DMatch DWildP $
DVarE fail_name `DAppE`
DLitE (StringL $ "Pattern match failure in " ++ ctxt)
]
where
bind_name = mk_qual_do_name mb_mod '(>>=)
mk_fail_name :: q Name
#if __GLASGOW_HASKELL__ >= 807
-- GHC 8.8 deprecates the MonadFailDesugaring extension since its effects
-- are always enabled. Furthermore, MonadFailDesugaring is no longer
-- enabled by default, so simply use MonadFail.fail. (That happens to
-- be the same as Prelude.fail in 8.8+.)
mk_fail_name = return fail_MonadFail_name
#else
mk_fail_name = do
mfd <- qIsExtEnabled LangExt.MonadFailDesugaring
return $ if mfd then fail_MonadFail_name else fail_Prelude_name
#endif
fail_MonadFail_name = mk_qual_do_name mb_mod 'Fail.fail
#if __GLASGOW_HASKELL__ < 807
fail_Prelude_name = mk_qual_do_name mb_mod 'Prelude.fail
#endif
-- | Desugar the contents of a parallel comprehension.
-- Returns a @Pat@ containing a tuple of all bound variables and an expression
-- to produce the values for those variables
dsParComp :: DsMonad q => [[Stmt]] -> q (DPat, DExp)
dsParComp [] = impossible "Empty list of parallel comprehension statements."
dsParComp [r] = do
let rv = foldMap extractBoundNamesStmt r
dsR <- dsComp (r ++ [mk_tuple_stmt rv])
return (mk_tuple_dpat rv, dsR)
dsParComp (q : rest) = do
let qv = foldMap extractBoundNamesStmt q
(rest_pat, rest_exp) <- dsParComp rest
dsQ <- dsComp (q ++ [mk_tuple_stmt qv])
let zipped = DAppE (DAppE (DVarE 'mzip) dsQ) rest_exp
return (DConP (tupleDataName 2) [] [mk_tuple_dpat qv, rest_pat], zipped)
-- helper function for dsParComp
mk_tuple_stmt :: OSet Name -> Stmt
mk_tuple_stmt name_set =
NoBindS (mkTupleExp (F.foldr ((:) . VarE) [] name_set))
-- helper function for dsParComp
mk_tuple_dpat :: OSet Name -> DPat
mk_tuple_dpat name_set =
mkTupleDPat (F.foldr ((:) . DVarP) [] name_set)
-- | Desugar a pattern, along with processing a (desugared) expression that
-- is the entire scope of the variables bound in the pattern.
dsPatOverExp :: DsMonad q => Pat -> DExp -> q (DPat, DExp)
dsPatOverExp pat exp = do
(pat', vars) <- runWriterT $ dsPat pat
let name_decs = map (uncurry (DValD . DVarP)) vars
return (pat', maybeDLetE name_decs exp)
-- | Desugar multiple patterns. Like 'dsPatOverExp'.
dsPatsOverExp :: DsMonad q => [Pat] -> DExp -> q ([DPat], DExp)
dsPatsOverExp pats exp = do
(pats', vars) <- runWriterT $ mapM dsPat pats
let name_decs = map (uncurry (DValD . DVarP)) vars
return (pats', maybeDLetE name_decs exp)
-- | Desugar a pattern, returning a list of (Name, DExp) pairs of extra
-- variables that must be bound within the scope of the pattern
dsPatX :: DsMonad q => Pat -> q (DPat, [(Name, DExp)])
dsPatX = runWriterT . dsPat
-- | Desugaring a pattern also returns the list of variables bound in as-patterns
-- and the values they should be bound to. This variables must be brought into
-- scope in the "body" of the pattern.
type PatM q = WriterT [(Name, DExp)] q
-- | Desugar a pattern.
dsPat :: DsMonad q => Pat -> PatM q DPat
dsPat (LitP lit) = return $ DLitP lit
dsPat (VarP n) = return $ DVarP n
dsPat (TupP pats) = DConP (tupleDataName (length pats)) [] <$> mapM dsPat pats
dsPat (UnboxedTupP pats) = DConP (unboxedTupleDataName (length pats)) [] <$>
mapM dsPat pats
#if __GLASGOW_HASKELL__ >= 901
dsPat (ConP name tys pats) = DConP name <$> mapM dsType tys <*> mapM dsPat pats
#else
dsPat (ConP name pats) = DConP name [] <$> mapM dsPat pats
#endif
dsPat (InfixP p1 name p2) = DConP name [] <$> mapM dsPat [p1, p2]
dsPat (UInfixP _ _ _) =
fail "Cannot desugar unresolved infix operators."
dsPat (ParensP pat) = dsPat pat
dsPat (TildeP pat) = DTildeP <$> dsPat pat
dsPat (BangP pat) = DBangP <$> dsPat pat
dsPat (AsP name pat) = do
pat' <- dsPat pat
pat'' <- lift $ removeWilds pat'
tell [(name, dPatToDExp pat'')]
return pat''
dsPat WildP = return DWildP
dsPat (RecP con_name field_pats) = do
con <- lift $ dataConNameToCon con_name
reordered <- reorder con
return $ DConP con_name [] reordered
where
reorder con = case con of
NormalC _name fields -> non_record fields
InfixC field1 _name field2 -> non_record [field1, field2]
RecC _name fields -> reorder_fields_pat fields
ForallC _ _ c -> reorder c
GadtC _names fields _ret_ty -> non_record fields
RecGadtC _names fields _ret_ty -> reorder_fields_pat fields
reorder_fields_pat fields = reorderFieldsPat con_name fields field_pats
non_record fields | null field_pats
-- Special case: record patterns are allowed for any
-- constructor, regardless of whether the constructor
-- actually was declared with records, provided that
-- no records are given in the pattern itself. (See #59).
--
-- Con{} desugars down to Con _ ... _.
= return $ replicate (length fields) DWildP
| otherwise = lift $ impossible
$ "Record syntax used with non-record constructor "
++ (show con_name) ++ "."
dsPat (ListP pats) = go pats
where go [] = return $ DConP '[] [] []
go (h : t) = do
h' <- dsPat h
t' <- go t
return $ DConP '(:) [] [h', t']
dsPat (SigP pat ty) = DSigP <$> dsPat pat <*> dsType ty
#if __GLASGOW_HASKELL__ >= 801
dsPat (UnboxedSumP pat alt arity) =
DConP (unboxedSumDataName alt arity) [] <$> ((:[]) <$> dsPat pat)
#endif
#if __GLASGOW_HASKELL__ >= 909
dsPat (TypeP ty) = DTypeP <$> dsType ty
dsPat (InvisP ty) = DInvisP <$> dsType ty
#endif
dsPat (ViewP _ _) =
fail "View patterns are not supported in th-desugar. Use pattern guards instead."
-- | Convert a 'DPat' to a 'DExp'. Fails on 'DWildP' and 'DInvisP'.
dPatToDExp :: DPat -> DExp
dPatToDExp (DLitP lit) = DLitE lit
dPatToDExp (DVarP name) = DVarE name
dPatToDExp (DConP name tys pats) = foldl DAppE (foldl DAppTypeE (DConE name) tys) (map dPatToDExp pats)
dPatToDExp (DTildeP pat) = dPatToDExp pat
dPatToDExp (DBangP pat) = dPatToDExp pat
dPatToDExp (DSigP pat ty) = DSigE (dPatToDExp pat) ty
dPatToDExp (DTypeP ty) = DTypeE ty
dPatToDExp DWildP = error "Internal error in th-desugar: wildcard in rhs of as-pattern"
dPatToDExp (DInvisP {}) = error "Internal error in th-desugar: invisible type pattern in rhs of as-pattern"
-- | Remove all wildcards from a pattern, replacing any wildcard with a fresh
-- variable
removeWilds :: DsMonad q => DPat -> q DPat
removeWilds p@(DLitP _) = return p
removeWilds p@(DVarP _) = return p
removeWilds (DConP con_name tys pats) = DConP con_name tys <$> mapM removeWilds pats
removeWilds (DTildeP pat) = DTildeP <$> removeWilds pat
removeWilds (DBangP pat) = DBangP <$> removeWilds pat
removeWilds (DSigP pat ty) = DSigP <$> removeWilds pat <*> pure ty
removeWilds (DTypeP ty) = pure $ DTypeP ty
removeWilds (DInvisP ty) = pure $ DInvisP ty
removeWilds DWildP = DVarP <$> newUniqueName "wild"
-- | Desugar @Info@
dsInfo :: DsMonad q => Info -> q DInfo
dsInfo (ClassI dec instances) = do
[ddec] <- dsDec dec
dinstances <- dsDecs instances
return $ DTyConI ddec (Just dinstances)
dsInfo (ClassOpI name ty parent) =
DVarI name <$> dsType ty <*> pure (Just parent)
dsInfo (TyConI dec) = do
[ddec] <- dsDec dec
return $ DTyConI ddec Nothing
dsInfo (FamilyI dec instances) = do
[ddec] <- dsDec dec
dinstances <- dsDecs instances
return $ DTyConI ddec (Just dinstances)
dsInfo (PrimTyConI name arity unlifted) =
return $ DPrimTyConI name arity unlifted
dsInfo (DataConI name ty parent) =
DVarI name <$> dsType ty <*> pure (Just parent)
dsInfo (VarI name ty Nothing) =
DVarI name <$> dsType ty <*> pure Nothing
dsInfo (VarI name _ (Just _)) =
impossible $ "Declaration supplied with variable: " ++ show name
dsInfo (TyVarI name ty) = DTyVarI name <$> dsType ty
#if __GLASGOW_HASKELL__ >= 801
dsInfo (PatSynI name ty) = DPatSynI name <$> dsType ty
#endif
-- | Desugar arbitrary @Dec@s
dsDecs :: DsMonad q => [Dec] -> q [DDec]
dsDecs = concatMapM dsDec
-- | Desugar a single @Dec@, perhaps producing multiple 'DDec's
dsDec :: DsMonad q => Dec -> q [DDec]
dsDec d@(FunD {}) = dsTopLevelLetDec d
dsDec d@(ValD {}) = dsTopLevelLetDec d
dsDec (DataD cxt n tvbs mk cons derivings) =
dsDataDec Data cxt n tvbs mk cons derivings
dsDec (NewtypeD cxt n tvbs mk con derivings) =
dsDataDec Newtype cxt n tvbs mk [con] derivings
dsDec (TySynD n tvbs ty) =
(:[]) <$> (DTySynD n <$> mapM dsTvbVis tvbs <*> dsType ty)
dsDec (ClassD cxt n tvbs fds decs) =
(:[]) <$> (DClassD <$> dsCxt cxt <*> pure n <*> mapM dsTvbVis tvbs
<*> pure fds <*> dsDecs decs)
dsDec (InstanceD over cxt ty decs) =
(:[]) <$> (DInstanceD over Nothing <$> dsCxt cxt <*> dsType ty <*> dsDecs decs)
dsDec d@(SigD {}) = dsTopLevelLetDec d
dsDec (ForeignD f) = (:[]) <$> (DForeignD <$> dsForeign f)
dsDec d@(InfixD {}) = dsTopLevelLetDec d
dsDec d@(PragmaD {}) = dsTopLevelLetDec d
dsDec (OpenTypeFamilyD tfHead) =
(:[]) <$> (DOpenTypeFamilyD <$> dsTypeFamilyHead tfHead)
dsDec (DataFamilyD n tvbs m_k) =
(:[]) <$> (DDataFamilyD n <$> mapM dsTvbVis tvbs <*> mapM dsType m_k)
#if __GLASGOW_HASKELL__ >= 807
dsDec (DataInstD cxt mtvbs lhs mk cons derivings) =
case unfoldType lhs of
(ConT n, tys) -> dsDataInstDec Data cxt n mtvbs tys mk cons derivings
(_, _) -> fail $ "Unexpected data instance LHS: " ++ pprint lhs
dsDec (NewtypeInstD cxt mtvbs lhs mk con derivings) =
case unfoldType lhs of
(ConT n, tys) -> dsDataInstDec Newtype cxt n mtvbs tys mk [con] derivings
(_, _) -> fail $ "Unexpected newtype instance LHS: " ++ pprint lhs
#else
dsDec (DataInstD cxt n tys mk cons derivings) =
dsDataInstDec Data cxt n Nothing (map TANormal tys) mk cons derivings
dsDec (NewtypeInstD cxt n tys mk con derivings) =
dsDataInstDec Newtype cxt n Nothing (map TANormal tys) mk [con] derivings
#endif
#if __GLASGOW_HASKELL__ >= 807
dsDec (TySynInstD eqn) = (:[]) <$> (DTySynInstD <$> dsTySynEqn unusedArgument eqn)
#else
dsDec (TySynInstD n eqn) = (:[]) <$> (DTySynInstD <$> dsTySynEqn n eqn)
#endif
dsDec (ClosedTypeFamilyD tfHead eqns) =
(:[]) <$> (DClosedTypeFamilyD <$> dsTypeFamilyHead tfHead
<*> mapM (dsTySynEqn (typeFamilyHeadName tfHead)) eqns)
dsDec (RoleAnnotD n roles) = return [DRoleAnnotD n roles]
#if __GLASGOW_HASKELL__ >= 801
dsDec (PatSynD n args dir pat) = do
dir' <- dsPatSynDir n dir
(pat', vars) <- dsPatX pat
unless (null vars) $
fail $ "Pattern synonym definition cannot contain as-patterns (@)."
return [DPatSynD n args dir' pat']
dsDec (PatSynSigD n ty) = (:[]) <$> (DPatSynSigD n <$> dsType ty)
dsDec (StandaloneDerivD mds cxt ty) =
(:[]) <$> (DStandaloneDerivD <$> mapM dsDerivStrategy mds
<*> pure Nothing <*> dsCxt cxt <*> dsType ty)
#else
dsDec (StandaloneDerivD cxt ty) =
(:[]) <$> (DStandaloneDerivD Nothing Nothing <$> dsCxt cxt <*> dsType ty)
#endif
dsDec (DefaultSigD n ty) = (:[]) <$> (DDefaultSigD n <$> dsType ty)
#if __GLASGOW_HASKELL__ >= 807
dsDec (ImplicitParamBindD {}) = impossible "Non-`let`-bound implicit param binding"
#endif
#if __GLASGOW_HASKELL__ >= 809
dsDec (KiSigD n ki) = (:[]) <$> (DKiSigD n <$> dsType ki)
#endif
#if __GLASGOW_HASKELL__ >= 903
dsDec (DefaultD tys) = (:[]) <$> (DDefaultD <$> mapM dsType tys)
#endif
#if __GLASGOW_HASKELL__ >= 906
dsDec (TypeDataD n tys mk cons) =
dsDataDec TypeData [] n tys mk cons []
#endif
-- | Desugar a 'DataD', 'NewtypeD', or 'TypeDataD'.
dsDataDec :: DsMonad q
=> DataFlavor -> Cxt -> Name -> [TyVarBndrVis]
-> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec]
dsDataDec nd cxt n tvbs mk cons derivings = do
tvbs' <- mapM dsTvbVis tvbs
let h98_tvbs = case mk of
-- If there's an explicit return kind, we're dealing with a
-- GADT, so this argument goes unused in dsCon.
Just {} -> unusedArgument
Nothing -> tvbs'
h98_return_type = nonFamilyDataReturnType n tvbs'
(:[]) <$> (DDataD nd <$> dsCxt cxt <*> pure n
<*> pure tvbs' <*> mapM dsType mk
<*> concatMapM (dsCon h98_tvbs h98_return_type) cons
<*> mapM dsDerivClause derivings)
-- | Desugar a 'DataInstD' or a 'NewtypeInstD'.
dsDataInstDec :: DsMonad q
=> DataFlavor -> Cxt -> Name -> Maybe [TyVarBndrUnit] -> [TypeArg]
-> Maybe Kind -> [Con] -> [DerivingClause] -> q [DDec]
dsDataInstDec nd cxt n mtvbs tys mk cons derivings = do
mtvbs' <- mapM (mapM dsTvbUnit) mtvbs
tys' <- mapM dsTypeArg tys
let lhs' = applyDType (DConT n) tys'
h98_tvbs =
changeDTVFlags defaultBndrFlag $
case (mk, mtvbs') of
-- If there's an explicit return kind, we're dealing with a
-- GADT, so this argument goes unused in dsCon.
(Just {}, _) -> unusedArgument
-- H98, and there is an explicit `forall` in front. Just reuse the
-- type variable binders from the `forall`.
(Nothing, Just tvbs') -> tvbs'
-- H98, and no explicit `forall`. Compute the bound variables
-- manually.
(Nothing, Nothing) -> dataFamInstTvbs tys'
h98_fam_inst_type = dataFamInstReturnType n tys'
(:[]) <$> (DDataInstD nd <$> dsCxt cxt <*> pure mtvbs'
<*> pure lhs' <*> mapM dsType mk
<*> concatMapM (dsCon h98_tvbs h98_fam_inst_type) cons
<*> mapM dsDerivClause derivings)
-- | Desugar a @FamilyResultSig@
dsFamilyResultSig :: DsMonad q => FamilyResultSig -> q DFamilyResultSig
dsFamilyResultSig NoSig = return DNoSig
dsFamilyResultSig (KindSig k) = DKindSig <$> dsType k
dsFamilyResultSig (TyVarSig tvb) = DTyVarSig <$> dsTvbUnit tvb
-- | Desugar a @TypeFamilyHead@
dsTypeFamilyHead :: DsMonad q => TypeFamilyHead -> q DTypeFamilyHead
dsTypeFamilyHead (TypeFamilyHead n tvbs result inj)
= DTypeFamilyHead n <$> mapM dsTvbVis tvbs
<*> dsFamilyResultSig result
<*> pure inj
typeFamilyHeadName :: TypeFamilyHead -> Name
typeFamilyHeadName (TypeFamilyHead n _ _ _) = n
-- | Desugar @Dec@s that can appear in a @let@ expression. See the
-- documentation for 'dsLetDec' for an explanation of what the return type
-- represents.
dsLetDecs :: DsMonad q => [Dec] -> q ([DLetDec], DExp -> DExp)
dsLetDecs decs = do
(let_decss, ip_binders) <- mapAndUnzipM dsLetDec decs
let let_decs :: [DLetDec]
let_decs = concat let_decss
ip_binder :: DExp -> DExp
ip_binder = foldr (.) id ip_binders
return (let_decs, ip_binder)
-- | Desugar a single 'Dec' that can appear in a @let@ expression.
-- This produces the following output:
--
-- * One or more 'DLetDec's (a single 'Dec' can produce multiple 'DLetDec's
-- in the event of a value declaration that binds multiple things by way
-- of pattern matching.
--
-- * A function of type @'DExp' -> 'DExp'@, which should be applied to the
-- expression immediately following the 'DLetDec's. This function prepends
-- binding forms for any implicit params that were bound in the argument
-- 'Dec'. (If no implicit params are bound, this is simply the 'id'
-- function.)
--
-- For instance, if the argument to 'dsLetDec' is the @?x = 42@ part of this
-- expression:
--
-- @
-- let { ?x = 42 } in ?x
-- @
--
-- Then the output is:
--
-- * @let new_x_val = 42@
--
-- * @\\z -> 'bindIP' \@\"x\" new_x_val z@
--
-- This way, the expression
-- @let { new_x_val = 42 } in 'bindIP' \@"x" new_x_val ('ip' \@\"x\")@ can be
-- formed. The implicit param binders always come after all the other
-- 'DLetDec's to support parallel assignment of implicit params.
dsLetDec :: DsMonad q => Dec -> q ([DLetDec], DExp -> DExp)
dsLetDec (FunD name clauses) = do
clauses' <- dsClauses (FunRhs name) clauses
return ([DFunD name clauses'], id)
dsLetDec (ValD pat body where_decs) = do
(pat', vars) <- dsPatX pat
body' <- dsBody body where_decs error_exp
let extras = uncurry (zipWith (DValD . DVarP)) $ unzip vars
return (DValD pat' body' : extras, id)
where
error_exp = mkErrorMatchExpr (LetDecRhs pat)
dsLetDec (SigD name ty) = do
ty' <- dsType ty
return ([DSigD name ty'], id)
#if __GLASGOW_HASKELL__ >= 909
dsLetDec (InfixD fixity ns_spec name) =
return ([DInfixD fixity ns_spec name], id)
#else
dsLetDec (InfixD fixity name) =
return ([DInfixD fixity NoNamespaceSpecifier name], id)
#endif
dsLetDec (PragmaD prag) = do
prag' <- dsPragma prag
return ([DPragmaD prag'], id)
#if __GLASGOW_HASKELL__ >= 807
dsLetDec (ImplicitParamBindD n e) = do
new_n_name <- qNewName $ "new_" ++ n ++ "_val"
e' <- dsExp e
let let_dec :: DLetDec
let_dec = DValD (DVarP new_n_name) e'
ip_binder :: DExp -> DExp
ip_binder = (DVarE 'bindIP `DAppTypeE`
DLitT (StrTyLit n) `DAppE`
DVarE new_n_name `DAppE`)
return ([let_dec], ip_binder)
#endif
dsLetDec _dec = impossible "Illegal declaration in let expression."
-- | Desugar a single 'Dec' corresponding to something that could appear after
-- the @let@ in a @let@ expression, but occurring at the top level. Because the
-- 'Dec' occurs at the top level, there is nothing that would correspond to the
-- @in ...@ part of the @let@ expression. As a consequence, this function does
-- not return a @'DExp' -> 'DExp'@ function corresonding to implicit param
-- binders (these cannot occur at the top level).
dsTopLevelLetDec :: DsMonad q => Dec -> q [DDec]
dsTopLevelLetDec = fmap (map DLetDec . fst) . dsLetDec
-- Note the use of fst above: we're silently throwing away any implicit param
-- binders that dsLetDec returns, since there is invariant that there will be
-- no implicit params in the first place.
-- | Desugar a single @Con@.
--
-- Because we always desugar @Con@s to GADT syntax (see the documentation for
-- 'DCon'), it is not always possible to desugar with just a 'Con' alone.
-- For instance, we must desugar:
--
-- @
-- data Foo a = forall b. MkFoo b
-- @
--
-- To this:
--
-- @
-- data Foo a :: Type where
-- MkFoo :: forall a b. b -> Foo a
-- @
--
-- If our only argument was @forall b. MkFoo b@, it would be somewhat awkward
-- to figure out (1) what the set of universally quantified type variables
-- (@[a]@) was, and (2) what the return type (@Foo a@) was. For this reason,
-- we require passing these as arguments. (If we desugar an actual GADT
-- constructor, these arguments are ignored.)
dsCon :: DsMonad q
=> [DTyVarBndrVis] -- ^ The universally quantified type variables
-- (used if desugaring a non-GADT constructor).
-> DType -- ^ The original data declaration's type
-- (used if desugaring a non-GADT constructor).
-> Con -> q [DCon]
dsCon univ_dtvbs data_type con = do
dcons' <- dsCon' con
return $ flip map dcons' $ \(n, dtvbs, dcxt, fields, m_gadt_type) ->
case m_gadt_type of
Nothing ->
let ex_dtvbs = dtvbs
expl_dtvbs = changeDTVFlags SpecifiedSpec univ_dtvbs ++
ex_dtvbs
impl_dtvbs = changeDTVFlags SpecifiedSpec $
toposortKindVarsOfTvbs expl_dtvbs in
DCon (impl_dtvbs ++ expl_dtvbs) dcxt n fields data_type
Just gadt_type ->
let univ_ex_dtvbs = dtvbs in
DCon univ_ex_dtvbs dcxt n fields gadt_type
-- Desugar a Con in isolation. The meaning of the returned DTyVarBndrs changes
-- depending on what the returned Maybe DType value is:
--
-- * If returning Just gadt_ty, then we've encountered a GadtC or RecGadtC,
-- so the returned DTyVarBndrs are both the universally and existentially
-- quantified tyvars.
-- * If returning Nothing, we're dealing with a non-GADT constructor, so
-- the returned DTyVarBndrs are the existentials only.
dsCon' :: DsMonad q