1 | {-# LANGUAGE TemplateHaskell #-} |
---|

2 | module ReifyPlusTypeInferenceBugs where |
---|

3 | |
---|

4 | import Language.Haskell.TH |
---|

5 | |
---|

6 | -- First problem: |
---|

7 | -- * reify doesn't return the expected type of names binded to |
---|

8 | -- polymorphic expressions |
---|

9 | |
---|

10 | -- a :: Num a => a |
---|

11 | -- uncommenting the line above fixes the problem |
---|

12 | a = 1 |
---|

13 | |
---|

14 | -- The following splice should print |
---|

15 | -- "inside b: forall a_0 . GHC.Num.Num a_0 => a_0" |
---|

16 | -- but instead, it merely prints a type variable "inside b: t_0" |
---|

17 | b = $(do VarI _ t _ _ <- reify 'a |
---|

18 | runIO $ putStrLn ("inside b: " ++ pprint t) |
---|

19 | [| undefined |]) |
---|

20 | |
---|

21 | |
---|

22 | -- Second problem: |
---|

23 | -- * reify doesn't return the expected type of names binded to |
---|

24 | -- TH-spliced expressions if no explicit type signature |
---|

25 | -- declaration is provided. |
---|

26 | |
---|

27 | |
---|

28 | -- c :: Bool |
---|

29 | -- uncommenting the line above fixes the problem |
---|

30 | c = $([| True |]) |
---|

31 | |
---|

32 | |
---|

33 | -- this splice should print "inside d: GHC.Base.Bool" |
---|

34 | -- but, again, it prints just a type variable: "inside d: t_0" |
---|

35 | d = $(do VarI _ t _ _ <- reify 'c |
---|

36 | runIO $ putStrLn ("inside d: " ++ pprint t) |
---|

37 | [| undefined |] ) |
---|

38 | |
---|

39 | -- Strangely enough, reify works differently if called inside a declaration |
---|

40 | -- splice. This time, the type returned is closer to be right |
---|

41 | -- but unnecesary type variables are included: |
---|

42 | -- "type of c: forall a_0 a_1 . GHC.Base.Bool" |
---|

43 | $(do VarI _ t _ _ <- reify 'c |
---|

44 | runIO $ putStrLn ("type of c: " ++ pprint t) |
---|

45 | return [] ) |
---|

46 | |
---|

47 | |
---|

48 | -- Even more strange is the fact that the order of declaration of |
---|

49 | -- splices seems to matter. Declaring the exact example again .... |
---|

50 | |
---|

51 | -- e :: Bool |
---|

52 | -- uncommenting the line above solves the problem |
---|

53 | e = $([| True |]) |
---|

54 | |
---|

55 | -- this splice works as expected!!! ??? |
---|

56 | -- "inside f: GHC.Base.Bool" |
---|

57 | f = $(do VarI _ t _ _ <- reify 'e |
---|

58 | runIO $ putStrLn ("inside f: " ++ pprint t) |
---|

59 | [| undefined |] ) |
---|

60 | |
---|

61 | -- Here, we still get unnecesary variables, but, for some reason, |
---|

62 | -- _just_ one in this case: |
---|

63 | -- "type of e: forall a_0 . GHC.Base.Bool" |
---|

64 | $(do VarI _ t _ _ <- reify 'e |
---|

65 | runIO $ putStrLn ("type of e: " ++ pprint t) |
---|

66 | return [] ) |
---|