1
+ {-# LANGUAGE RankNTypes #-}
2
+ {-# LANGUAGE ScopedTypeVariables #-}
3
+
1
4
module Main where
2
5
3
- import qualified Control.Monad.Fail as Fail
4
- import qualified Language.Haskell.Exts as Exts
5
- import qualified Language.Haskell.Exts.Extension as Extension
6
- import qualified Language.Haskell.Exts.Parser as Parser
6
+ import qualified Control.Monad.Fail as Fail
7
+ import Data.Data (Data , cast , gfoldl )
8
+ import Data.Functor.Const
9
+ (Const (Const , getConst ))
10
+ import qualified Language.Haskell.Exts as Exts
11
+ import qualified Language.Haskell.Exts.Extension as Extension
12
+ import qualified Language.Haskell.Exts.Parser as Parser
7
13
import Language.Haskell.Meta.Parse
8
14
import Language.Haskell.Meta.Syntax.Translate
9
- import qualified Language.Haskell.TH as TH
10
- import Test.HUnit (Assertion , (@?=) )
15
+ import qualified Language.Haskell.TH as TH
16
+ import Test.HUnit (Assertion , (@?=) )
11
17
import Test.Tasty
12
18
(TestTree , defaultMain , testGroup )
13
- import Test.Tasty.HUnit (testCase )
19
+ import Test.Tasty.HUnit (testCase )
14
20
15
21
type Test = TestTree
16
22
@@ -27,14 +33,38 @@ derivingClausesTest :: Test
27
33
derivingClausesTest = testCase " Deriving clauses preserved" $
28
34
roundTripDecls " data Foo = Foo deriving (A, B, C)"
29
35
30
- -- Very ugly test, illustrating incorrect order of promoted type tuples reconstructed into TH
31
36
orderInTypeTuples :: Test
32
- orderInTypeTuples = testCase " Ensure that type tuples reconstructed in proper order" $ do
33
- let Parser. ParseOk parsed = show . toExp <$> Parser. parseExpWithMode mode " getField @'(\" a\" , \" b\" , \" c\" ) localVar"
34
- parsed @?= expected
37
+ orderInTypeTuples =
38
+ testCase " Ensure that type tuples reconstructed in proper order" $ do
39
+ expected @?= actual
40
+ where
41
+ expected :: [TH. TyLit ]
42
+ expected = collectAll (toExp parsed)
43
+ actual = [TH. StrTyLit " a" , TH. StrTyLit " b" ]
44
+
45
+ parsed :: Exts. Exp Exts. SrcSpanInfo
46
+ parsed = case Exts. parseExpWithMode mode " foo @'(\" a\" , \" b\" )" of
47
+ Exts. ParseOk v -> v
48
+ e -> error $ show e
49
+ mode :: Exts. ParseMode
50
+ mode = Exts. defaultParseMode {
51
+ Exts. extensions = [
52
+ Exts. EnableExtension Exts. TypeApplications
53
+ , Exts. EnableExtension Exts. DataKinds
54
+ ]
55
+ }
56
+
57
+ collectAll :: (Data a , Data b ) => a -> [b ]
58
+ collectAll = ($ [] ) . go
35
59
where
36
- mode = Parser. defaultParseMode { Parser. extensions = [Extension. EnableExtension Extension. TypeApplications , Extension. EnableExtension Extension. DataKinds ] }
37
- expected = " (AppE (AppTypeE (VarE getField) (AppT (AppT (AppT (PromotedTupleT 3) (LitT (StrTyLit \" a\" ))) (LitT (StrTyLit \" b\" ))) (LitT (StrTyLit \" c\" )))) (VarE localVar))"
60
+ go :: forall a b . (Data a , Data b ) => a -> [b ] -> [b ]
61
+ go = \ x ->
62
+ case cast x of
63
+ Just x' -> (x' : )
64
+ Nothing -> getConst $ gfoldl ap (const $ Const id ) x
65
+ where
66
+ ap :: Data x => Const ([b ] -> [b ]) (x -> y ) -> x -> Const ([b ] -> [b ]) y
67
+ ap (Const acc) x = Const $ acc . go x
38
68
39
69
typeAppMode :: Exts. ParseMode
40
70
typeAppMode = Parser. defaultParseMode { Parser. extensions = [Extension. EnableExtension Extension. TypeApplications ] }
0 commit comments