Testsuite: tabs -> spaces [skip ci]
[ghc.git] / testsuite / tests / gadt / karl2.hs
1 {-# LANGUAGE GADTs, KindSignatures #-}
2
3 module Expr0 where
4
5 -- See Trac #301
6 -- This one *does* use GADTs (Fct)
7
8 data Expr :: * -> * where
9 Const :: Show a => a -> Expr a
10 Apply :: Fct a b -> Expr a -> Expr b
11
12 data Fct :: * -> * -> * where
13 Succ :: Fct Int Int
14 EqZero :: Fct Int Bool
15 Add :: Fct Int (Int -> Int)
16
17 ------------------------------
18 e1 :: Expr Int
19 e1 = Apply Succ (Const 41)
20
21 e2 :: Expr Bool
22 e2 = Apply EqZero e1
23
24 e3 :: Expr (Int -> Int)
25 e3 = Apply Add e1
26
27 ------------------------------
28 eval :: Expr a -> a
29 eval (Const c) = c
30 eval (Apply f a) = evalFct f $ eval a
31
32 evalFct :: Fct a b -> a -> b
33 evalFct Succ = succ
34 evalFct EqZero = (0 ==)
35 evalFct Add = (+)
36
37
38 {- Up to here, everything works nicely:
39
40 \begin{verbatim}
41 *Expr0> eval e1
42 42
43 *Expr0> eval e2
44 False
45 *Expr0> eval e3 5
46 47
47 \end{verbatim}
48
49 But let us now try to define a |Show| instance.
50 For |Fct|, this is not a problem:
51 -}
52
53 instance Show (Fct a b) where
54 show Succ = "S"
55 show EqZero = "isZero"
56 show Add = "add"
57
58 showsExpr :: Expr a -> ShowS
59 showsExpr (Const c) = shows c
60 showsExpr (Apply f a) =
61 ('(' :) . shows f . (' ' :) . showsExpr a . (')' :)
62
63 instance Show (Expr a) where
64 showsPrec _ (Const c) = shows c
65 showsPrec _ (Apply f a) =
66 ('(' :) . shows f . (' ' :) . shows a . (')' :)
67
68 {- But we used to get a complaint about the |Const| alternative (then
69 line 56) that documents that the constraint in the type of |Const|
70 must have been ignored:
71
72 \begin{verbatim}
73 No instance for (Show a)
74 arising from use of `shows' at Expr0.lhs:56:22-26
75 Probable fix: add (Show a) to the type signature(s) for `showsExpr'
76 In the definition of `showsExpr': showsExpr (Const c) = shows c
77 \end{verbatim}
78
79 But if we do that, the recursive call is of course still unsatisfied:
80 \begin{verbatim}
81 No instance for (Show a)
82 arising from use of `showsExpr' at Expr0.lhs:65:34-42
83 Probable fix: add (Show a) to the existential context for `Apply'
84 In the first argument of `(.)', namely `showsExpr a'
85 In the second argument of `(.)', namely `(showsExpr a) . ((')' :))'
86 In the second argument of `(.)', namely
87 `((' ' :)) . ((showsExpr a) . ((')' :)))'
88 \end{verbatim}
89
90 Following also the advice given in this last error message
91 actually makes GHC accept this, and then we can say:
92
93 \begin{verbatim}
94 *Expr0> showsExpr e1 ""
95 "(S 41)"
96 *Expr0> showsExpr e2 ""
97 "(isZero (S 41))"
98 \end{verbatim}
99
100 However, following this advice is counterintuitive
101 and should be unnecessary
102 since the |Show| instance for argument types
103 is only ever used in the const case.
104 We get:
105
106 \begin{verbatim}
107 *Expr0> showsExpr e3 ""
108
109 <interactive>:1:0:
110 No instance for (Show (Int -> Int))
111 arising from use of `showsExpr' at <interactive>:1:0-8
112 Probable fix: add an instance declaration for (Show (Int -> Int))
113 In the definition of `it': it = showsExpr e3 ""
114 \end{verbatim}
115
116 But of course we would expect the following:
117
118 \begin{verbatim}
119 *Expr0> showsExpr e3 ""
120 "(add (S 41))"
121 \end{verbatim}
122
123
124 \bigskip
125 The error messages are almost the same
126 if we define a |Show| instance directly
127 (line 90 was the |Const| alternative):
128
129 \begin{verbatim}
130 Could not deduce (Show a) from the context (Show (Expr a))
131 arising from use of `shows' at Expr0.lhs:90:26-30
132 Probable fix: add (Show a) to the class or instance method `showsPrec'
133 \end{verbatim}
134 -}
135
136