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
-- |
-- Description: AST for curry code
-- Author     : Kai-Oliver Prott
-- Version    : November 2024
--
-- An implementation of the Curry AST from curry-frontend.
module Curry.Types where

import Curry.Span
import Curry.SpanInfo
import Curry.Ident
import Curry.Position

-- | This datatype is copied from curry-base.
data Module a = Module SpanInfo LayoutInfo [ModulePragma] ModuleIdent
                       (Maybe ExportSpec) [ImportDecl] [Decl a]
    deriving (Eq, Read, Show)

data ModulePragma
  = LanguagePragma SpanInfo [Extension]
  | OptionsPragma  SpanInfo (Maybe Tool) String
    deriving (Eq, Read, Show)

data ExportSpec = Exporting SpanInfo [Export]
    deriving (Eq, Read, Show)

data Export
  = Export         SpanInfo QualIdent
  | ExportTypeWith SpanInfo QualIdent [Ident]
  | ExportTypeAll  SpanInfo QualIdent
  | ExportModule   SpanInfo ModuleIdent
    deriving (Eq, Read, Show)

data ImportDecl = ImportDecl SpanInfo ModuleIdent Qualified
                             (Maybe ModuleIdent) (Maybe ImportSpec)
    deriving (Eq, Read, Show)

type Qualified = Bool

data ImportSpec
  = Importing SpanInfo [Import]
  | Hiding    SpanInfo [Import]
    deriving (Eq, Read, Show)

data Import
  = Import         SpanInfo Ident
  | ImportTypeWith SpanInfo Ident [Ident]
  | ImportTypeAll  SpanInfo Ident
    deriving (Eq, Read, Show)

data Decl a
  = InfixDecl        SpanInfo Infix (Maybe Precedence) [Ident]                     -- infixl 5 (op), `fun`
  | DataDecl         SpanInfo Ident [Ident] [ConstrDecl] [QualIdent]               -- data C a b = C1 a | C2 b deriving (D, ...)
  | ExternalDataDecl SpanInfo Ident [Ident]
  | NewtypeDecl      SpanInfo Ident [Ident] NewConstrDecl [QualIdent]              -- newtype C a b = C a b deriving (D, ...)
  | TypeDecl         SpanInfo Ident [Ident] TypeExpr                               -- type C a b = D a b
  | TypeSig          SpanInfo [Ident] QualTypeExpr                                 -- f, g :: Bool
  | FunctionDecl     SpanInfo a Ident [Equation a]                                 -- f True = 1 ; f False = 0
  | ExternalDecl     SpanInfo [Var a]                                              -- f, g external
  | PatternDecl      SpanInfo (Pattern a) (Rhs a)                                  -- Just x = ...
  | FreeDecl         SpanInfo [Var a]                                              -- x, y free
  | DefaultDecl      SpanInfo [TypeExpr]                                           -- default (Int, Float)
  | ClassDecl        SpanInfo LayoutInfo Context Ident [Ident] [FunDep] [Decl a]   -- class C a => D a b | a -> b where {TypeSig|InfixDecl|FunctionDecl}
  | InstanceDecl     SpanInfo LayoutInfo Context QualIdent [InstanceType] [Decl a] -- instance C a => M.D (N.T a b c) where {FunctionDecl}
  deriving (Eq, Read, Show)

type Precedence = Int

data Infix
  = InfixL
  | InfixR
  | Infix
    deriving (Eq, Read, Show)

data ConstrDecl
  = ConstrDecl SpanInfo Ident [TypeExpr]
  | ConOpDecl  SpanInfo TypeExpr Ident TypeExpr
  | RecordDecl SpanInfo Ident [FieldDecl]
    deriving (Eq, Read, Show)

data NewConstrDecl
  = NewConstrDecl SpanInfo Ident TypeExpr
  | NewRecordDecl SpanInfo Ident (Ident, TypeExpr)
   deriving (Eq, Read, Show)

data FieldDecl = FieldDecl SpanInfo [Ident] TypeExpr
  deriving (Eq, Read, Show)

data TypeExpr
  = ConstructorType SpanInfo QualIdent
  | ApplyType       SpanInfo TypeExpr TypeExpr
  | VariableType    SpanInfo Ident
  | TupleType       SpanInfo [TypeExpr]
  | ListType        SpanInfo TypeExpr
  | ArrowType       SpanInfo TypeExpr TypeExpr
  | ParenType       SpanInfo TypeExpr
  | ForallType      SpanInfo [Ident] TypeExpr
  deriving (Eq, Read, Show)

data QualTypeExpr = QualTypeExpr SpanInfo Context TypeExpr
    deriving (Eq, Read, Show)

type Context = [Constraint]

data Constraint = Constraint SpanInfo QualIdent [TypeExpr]
  deriving (Eq, Read, Show)

type InstanceType = TypeExpr

data FunDep = FunDep SpanInfo [Ident] [Ident]
  deriving (Eq, Read, Show)

data Equation a = Equation SpanInfo (Maybe a) (Lhs a) (Rhs a)
  deriving (Eq, Read, Show)

data Lhs a
  = FunLhs SpanInfo Ident [Pattern a]
  | OpLhs  SpanInfo (Pattern a) Ident (Pattern a)
  | ApLhs  SpanInfo (Lhs a) [Pattern a]
  deriving (Eq, Read, Show)

data Rhs a
  = SimpleRhs  SpanInfo LayoutInfo (Expression a) [Decl a]
  | GuardedRhs SpanInfo LayoutInfo [CondExpr a]   [Decl a]
  deriving (Eq, Read, Show)

data CondExpr a = CondExpr SpanInfo (Expression a) (Expression a)
  deriving (Eq, Read, Show)

data Literal
  = Char   Char
  | Int    Int
  | Float  Float
  | String String
  deriving (Eq, Read, Show)

data Pattern a
  = LiteralPattern     SpanInfo a Literal
  | NegativePattern    SpanInfo a Literal
  | VariablePattern    SpanInfo a Ident
  | ConstructorPattern SpanInfo a QualIdent [Pattern a]
  | InfixPattern       SpanInfo a (Pattern a) QualIdent (Pattern a)
  | ParenPattern       SpanInfo (Pattern a)
  | RecordPattern      SpanInfo a QualIdent [Field (Pattern a)]
  | TuplePattern       SpanInfo [Pattern a]
  | ListPattern        SpanInfo a [Pattern a]
  | AsPattern          SpanInfo Ident (Pattern a)
  | LazyPattern        SpanInfo (Pattern a)
  | FunctionPattern    SpanInfo a QualIdent [Pattern a]
  | InfixFuncPattern   SpanInfo a (Pattern a) QualIdent (Pattern a)
  deriving (Eq, Read, Show)

data Expression a
  = Literal           SpanInfo a Literal
  | Variable          SpanInfo a QualIdent
  | Constructor       SpanInfo a QualIdent
  | Paren             SpanInfo (Expression a)
  | Typed             SpanInfo (Expression a) QualTypeExpr
  | Record            SpanInfo a QualIdent [Field (Expression a)]    -- C {l1 = e1,..., ln = en}
  | RecordUpdate      SpanInfo (Expression a) [Field (Expression a)] -- e {l1 = e1,..., ln = en}
  | Tuple             SpanInfo [Expression a]
  | List              SpanInfo a [Expression a]
  | ListCompr         SpanInfo (Expression a) [Statement a]   -- the ref corresponds to the main list
  | EnumFrom          SpanInfo (Expression a)
  | EnumFromThen      SpanInfo (Expression a) (Expression a)
  | EnumFromTo        SpanInfo (Expression a) (Expression a)
  | EnumFromThenTo    SpanInfo (Expression a) (Expression a) (Expression a)
  | UnaryMinus        SpanInfo (Expression a)
  | Apply             SpanInfo (Expression a) (Expression a)
  | InfixApply        SpanInfo (Expression a) (InfixOp a) (Expression a)
  | LeftSection       SpanInfo (Expression a) (InfixOp a)
  | RightSection      SpanInfo (InfixOp a) (Expression a)
  | Lambda            SpanInfo [Pattern a] (Expression a)
  | Let               SpanInfo LayoutInfo [Decl a] (Expression a)
  | Do                SpanInfo LayoutInfo [Statement a] (Expression a)
  | IfThenElse        SpanInfo (Expression a) (Expression a) (Expression a)
  | Case              SpanInfo LayoutInfo CaseType (Expression a) [Alt a]
  deriving (Eq, Read, Show)

data InfixOp a
  = InfixOp     a QualIdent
  | InfixConstr a QualIdent
  deriving (Eq, Read, Show)

data Statement a
  = StmtExpr SpanInfo (Expression a)
  | StmtDecl SpanInfo LayoutInfo [Decl a]
  | StmtBind SpanInfo (Pattern a) (Expression a)
  deriving (Eq, Read, Show)

data CaseType
  = Rigid
  | Flex
  deriving (Eq, Read, Show)

data Alt a = Alt SpanInfo (Pattern a) (Rhs a)
  deriving (Eq, Read, Show)

data Field a = Field SpanInfo QualIdent a
  deriving (Eq, Read, Show)

data Var a = Var a Ident
  deriving (Eq, Read, Show)

data Goal a = Goal SpanInfo LayoutInfo (Expression a) [Decl a]
  deriving (Eq, Read, Show)

data Extension
  = KnownExtension   SpanInfo KnownExtension
  | UnknownExtension SpanInfo String
  deriving (Eq, Read, Show)

data KnownExtension
  = AnonFreeVars              -- ^ anonymous free variables
  | CPP                       -- ^ C preprocessor
  | FlexibleContexts          -- ^ no restrictions on context form
  | FlexibleInstances         -- ^ no restrictions on instance syntax
  | FunctionalDependencies    -- ^ functional dependencies
  | FunctionalPatterns        -- ^ functional patterns
  | MultiParamTypeClasses     -- ^ multi-parameter type classes
  | NegativeLiterals          -- ^ negative literals
  | NoAnonFreeVars            -- ^ no anonymous free variables
  | NoFunctionalPatterns      -- ^ no functional patterns
  | NoImplicitPrelude         -- ^ no implicit import of the prelude
  | NoDataDeriving            -- ^ no implicit deriving of the Data class
  deriving (Eq, Read, Show)

data KnownTool = KICS2 | PAKCS | CYMAKE | FRONTEND
    deriving (Eq, Read, Show, Enum, Bounded)

data Tool = KnownTool KnownTool | UnknownTool String
    deriving (Eq, Read, Show)

instance HasSpanInfo (Module a) where
  getSpanInfo (Module sp _ _ _ _ _ _) = sp
  setSpanInfo sp (Module _ li ps m es is ds) = Module sp li ps m es is ds

instance HasSpanInfo (Decl a) where
  getSpanInfo (InfixDecl        sp _ _ _)       = sp
  getSpanInfo (DataDecl         sp _ _ _ _)     = sp
  getSpanInfo (ExternalDataDecl sp _ _)         = sp
  getSpanInfo (NewtypeDecl      sp _ _ _ _)     = sp
  getSpanInfo (TypeDecl         sp _ _ _)       = sp
  getSpanInfo (TypeSig          sp _ _)         = sp
  getSpanInfo (FunctionDecl     sp _ _ _)       = sp
  getSpanInfo (ExternalDecl     sp _)           = sp
  getSpanInfo (PatternDecl      sp _ _)         = sp
  getSpanInfo (FreeDecl         sp _)           = sp
  getSpanInfo (DefaultDecl      sp _)           = sp
  getSpanInfo (ClassDecl        sp _ _ _ _ _ _) = sp
  getSpanInfo (InstanceDecl     sp _ _ _ _ _)   = sp

  setSpanInfo sp (InfixDecl        _ fix prec ops)           = InfixDecl sp fix prec ops
  setSpanInfo sp (DataDecl         _ tc tvs cs clss)         = DataDecl sp tc tvs cs clss
  setSpanInfo sp (ExternalDataDecl _ tc tvs)                 = ExternalDataDecl sp tc tvs
  setSpanInfo sp (NewtypeDecl      _ tc tvs nc clss)         = NewtypeDecl sp tc tvs nc clss
  setSpanInfo sp (TypeDecl         _ tc tvs ty)              = TypeDecl sp tc tvs ty
  setSpanInfo sp (TypeSig          _ fs qty)                 = TypeSig sp fs qty
  setSpanInfo sp (FunctionDecl     _ a f' eqs)               = FunctionDecl sp a f' eqs
  setSpanInfo sp (ExternalDecl     _ vs)                     = ExternalDecl sp vs
  setSpanInfo sp (PatternDecl      _ t rhs)                  = PatternDecl sp t rhs
  setSpanInfo sp (FreeDecl         _ vs)                     = FreeDecl sp vs
  setSpanInfo sp (DefaultDecl      _ tys)                    = DefaultDecl sp tys
  setSpanInfo sp (ClassDecl     _ li cx cls clsvar fdeps ds) = ClassDecl sp li cx cls clsvar fdeps ds
  setSpanInfo sp (InstanceDecl  _ li cx qcls inst ds)        = InstanceDecl sp li cx qcls inst ds

instance HasSpanInfo (Equation a) where
  getSpanInfo (Equation spi _ _ _) = spi
  setSpanInfo spi (Equation _ t lhs rhs) = Equation spi t lhs rhs

instance HasSpanInfo ModulePragma where
  getSpanInfo (LanguagePragma sp _  ) = sp
  getSpanInfo (OptionsPragma  sp _ _) = sp

  setSpanInfo sp (LanguagePragma _ ex ) = LanguagePragma sp ex
  setSpanInfo sp (OptionsPragma  _ t a) = OptionsPragma sp t a

instance HasSpanInfo ExportSpec where
  getSpanInfo (Exporting sp _) = sp
  setSpanInfo sp (Exporting _ ex) = Exporting sp ex

instance HasSpanInfo Export where
  getSpanInfo (Export sp _)           = sp
  getSpanInfo (ExportTypeWith sp _ _) = sp
  getSpanInfo (ExportTypeAll sp _)    = sp
  getSpanInfo (ExportModule sp _)     = sp

  setSpanInfo sp (Export _ qid)            = Export sp qid
  setSpanInfo sp (ExportTypeWith _ qid cs) = ExportTypeWith sp qid cs
  setSpanInfo sp (ExportTypeAll _ qid)     = ExportTypeAll sp qid
  setSpanInfo sp (ExportModule _ mid)      = ExportModule sp mid

instance HasSpanInfo ImportDecl where
  getSpanInfo (ImportDecl sp _ _ _ _) = sp
  setSpanInfo sp (ImportDecl _ mid q as spec) = ImportDecl sp mid q as spec

instance HasSpanInfo ImportSpec where
  getSpanInfo (Importing sp _) = sp
  getSpanInfo (Hiding    sp _) = sp

  setSpanInfo sp (Importing _ im) = Importing sp im
  setSpanInfo sp (Hiding    _ im) = Hiding sp im

instance HasSpanInfo Import where
  getSpanInfo (Import sp _)           = sp
  getSpanInfo (ImportTypeWith sp _ _) = sp
  getSpanInfo (ImportTypeAll sp _)    = sp

  setSpanInfo sp (Import _ qid)            = Import sp qid
  setSpanInfo sp (ImportTypeWith _ qid cs) = ImportTypeWith sp qid cs
  setSpanInfo sp (ImportTypeAll _ qid)     = ImportTypeAll sp qid

instance HasSpanInfo ConstrDecl where
  getSpanInfo (ConstrDecl sp _ _)   = sp
  getSpanInfo (ConOpDecl  sp _ _ _) = sp
  getSpanInfo (RecordDecl sp _ _)   = sp

  setSpanInfo sp (ConstrDecl _ idt ty)      = ConstrDecl sp idt ty
  setSpanInfo sp (ConOpDecl  _ ty1 idt ty2) = ConOpDecl sp ty1 idt ty2
  setSpanInfo sp (RecordDecl _ idt fd)      = RecordDecl sp idt fd

instance HasSpanInfo NewConstrDecl where
  getSpanInfo (NewConstrDecl sp _ _)   = sp
  getSpanInfo (NewRecordDecl sp _ _)   = sp

  setSpanInfo sp (NewConstrDecl _ idt ty)  = NewConstrDecl sp idt ty
  setSpanInfo sp (NewRecordDecl _ idt fty) = NewRecordDecl sp idt fty

instance HasSpanInfo FieldDecl where
    getSpanInfo (FieldDecl sp _ _) = sp
    setSpanInfo sp (FieldDecl _ idt ty) = FieldDecl sp idt ty

instance HasSpanInfo TypeExpr where
  getSpanInfo (ConstructorType sp _) = sp
  getSpanInfo (ApplyType sp _ _)     = sp
  getSpanInfo (VariableType sp _)    = sp
  getSpanInfo (TupleType sp _)       = sp
  getSpanInfo (ListType sp _)        = sp
  getSpanInfo (ArrowType sp _ _)     = sp
  getSpanInfo (ParenType sp _)       = sp
  getSpanInfo (ForallType sp _ _)    = sp

  setSpanInfo sp (ConstructorType _ qid) = ConstructorType sp qid
  setSpanInfo sp (ApplyType _ ty1 ty2)   = ApplyType sp ty1 ty2
  setSpanInfo sp (VariableType _ idt)    = VariableType sp idt
  setSpanInfo sp (TupleType _ tys)       = TupleType sp tys
  setSpanInfo sp (ListType _ ty)         = ListType sp ty
  setSpanInfo sp (ArrowType _ ty1 ty2)   = ArrowType sp ty1 ty2
  setSpanInfo sp (ParenType _ ty)        = ParenType sp ty
  setSpanInfo sp (ForallType _ idt ty)   = ForallType sp idt ty

instance HasSpanInfo QualTypeExpr where
  getSpanInfo (QualTypeExpr sp _ _) = sp
  setSpanInfo sp (QualTypeExpr _ cx ty) = QualTypeExpr sp cx ty

instance HasSpanInfo Constraint where
  getSpanInfo (Constraint sp _ _) = sp
  setSpanInfo sp (Constraint _ qid ty) = Constraint sp qid ty

instance HasSpanInfo (Lhs a) where
  getSpanInfo (FunLhs sp _ _)   = sp
  getSpanInfo (OpLhs  sp _ _ _) = sp
  getSpanInfo (ApLhs  sp _ _)   = sp

  setSpanInfo sp (FunLhs _ idt ps)    = FunLhs sp idt ps
  setSpanInfo sp (OpLhs  _ p1 idt p2) = OpLhs sp p1 idt p2
  setSpanInfo sp (ApLhs  _ lhs ps)    = ApLhs sp lhs ps

instance HasSpanInfo (Rhs a) where
  getSpanInfo (SimpleRhs sp _ _ _)  = sp
  getSpanInfo (GuardedRhs sp _ _ _) = sp

  setSpanInfo sp (SimpleRhs _ li ex ds)  = SimpleRhs sp li ex ds
  setSpanInfo sp (GuardedRhs _ li cs ds) = GuardedRhs sp li cs ds

instance HasSpanInfo (CondExpr a) where
    getSpanInfo (CondExpr sp _ _) = sp
    setSpanInfo sp (CondExpr _ e1 e2) = CondExpr sp e1 e2

instance HasSpanInfo (Pattern a) where
  getSpanInfo (LiteralPattern  sp _ _)      = sp
  getSpanInfo (NegativePattern sp _ _)      = sp
  getSpanInfo (VariablePattern sp _ _)      = sp
  getSpanInfo (ConstructorPattern sp _ _ _) = sp
  getSpanInfo (InfixPattern sp _ _ _ _)     = sp
  getSpanInfo (ParenPattern sp _)           = sp
  getSpanInfo (RecordPattern sp _ _ _)      = sp
  getSpanInfo (TuplePattern sp _)           = sp
  getSpanInfo (ListPattern sp _ _)          = sp
  getSpanInfo (AsPattern sp _ _)            = sp
  getSpanInfo (LazyPattern sp _)            = sp
  getSpanInfo (FunctionPattern sp _ _ _)    = sp
  getSpanInfo (InfixFuncPattern sp _ _ _ _) = sp

  setSpanInfo sp (LiteralPattern _ a l)          = LiteralPattern sp a l
  setSpanInfo sp (NegativePattern _ a l)         = NegativePattern sp a l
  setSpanInfo sp (VariablePattern _ a v)         = VariablePattern sp a v
  setSpanInfo sp (ConstructorPattern _ a c ts)   = ConstructorPattern sp a c ts
  setSpanInfo sp (InfixPattern _ a t1 op t2)     = InfixPattern sp a t1 op t2
  setSpanInfo sp (ParenPattern _ t)              = ParenPattern sp t
  setSpanInfo sp (RecordPattern _ a c fs)        = RecordPattern sp a c fs
  setSpanInfo sp (TuplePattern _ ts)             = TuplePattern sp ts
  setSpanInfo sp (ListPattern _ a ts)            = ListPattern sp a ts
  setSpanInfo sp (AsPattern _ v t)               = AsPattern sp v t
  setSpanInfo sp (LazyPattern _ t)               = LazyPattern sp t
  setSpanInfo sp (FunctionPattern _ a f' ts)     = FunctionPattern sp a f' ts
  setSpanInfo sp (InfixFuncPattern _ a t1 op t2) = InfixFuncPattern sp a t1 op t2

instance HasSpanInfo (Expression a) where
  getSpanInfo (Literal sp _ _)          = sp
  getSpanInfo (Variable sp _ _)         = sp
  getSpanInfo (Constructor sp _ _)      = sp
  getSpanInfo (Paren sp _)              = sp
  getSpanInfo (Typed sp _ _)            = sp
  getSpanInfo (Record sp _ _ _)         = sp
  getSpanInfo (RecordUpdate sp _ _)     = sp
  getSpanInfo (Tuple sp _)              = sp
  getSpanInfo (List sp _ _)             = sp
  getSpanInfo (ListCompr sp _ _)        = sp
  getSpanInfo (EnumFrom sp _)           = sp
  getSpanInfo (EnumFromThen sp _ _)     = sp
  getSpanInfo (EnumFromTo sp _ _)       = sp
  getSpanInfo (EnumFromThenTo sp _ _ _) = sp
  getSpanInfo (UnaryMinus sp _)         = sp
  getSpanInfo (Apply sp _ _)            = sp
  getSpanInfo (InfixApply sp _ _ _)     = sp
  getSpanInfo (LeftSection sp _ _)      = sp
  getSpanInfo (RightSection sp _ _)     = sp
  getSpanInfo (Lambda sp _ _)           = sp
  getSpanInfo (Let sp _ _ _)            = sp
  getSpanInfo (Do sp _ _ _)             = sp
  getSpanInfo (IfThenElse sp _ _ _)     = sp
  getSpanInfo (Case sp _ _ _ _)         = sp

  setSpanInfo sp (Literal _ a l)             = Literal sp a l
  setSpanInfo sp (Variable _ a v)            = Variable sp a v
  setSpanInfo sp (Constructor _ a c)         = Constructor sp a c
  setSpanInfo sp (Paren _ e)                 = Paren sp e
  setSpanInfo sp (Typed _ e qty)             = Typed sp e qty
  setSpanInfo sp (Record _ a c fs)           = Record sp a c fs
  setSpanInfo sp (RecordUpdate _ e fs)       = RecordUpdate sp e fs
  setSpanInfo sp (Tuple _ es)                = Tuple sp es
  setSpanInfo sp (List _ a es)               = List sp a es
  setSpanInfo sp (ListCompr _ e stms)        = ListCompr sp e stms
  setSpanInfo sp (EnumFrom _ e)              = EnumFrom sp e
  setSpanInfo sp (EnumFromThen _ e1 e2)      = EnumFromThen sp e1 e2
  setSpanInfo sp (EnumFromTo _ e1 e2)        = EnumFromTo sp e1 e2
  setSpanInfo sp (EnumFromThenTo _ e1 e2 e3) = EnumFromThenTo sp e1 e2 e3
  setSpanInfo sp (UnaryMinus _ e)            = UnaryMinus sp e
  setSpanInfo sp (Apply _ e1 e2)             = Apply sp e1 e2
  setSpanInfo sp (InfixApply _ e1 op e2)     = InfixApply sp e1 op e2
  setSpanInfo sp (LeftSection _ e op)        = LeftSection sp e op
  setSpanInfo sp (RightSection _ op e)       = RightSection sp op e
  setSpanInfo sp (Lambda _ ts e)             = Lambda sp ts e
  setSpanInfo sp (Let _ li ds e)             = Let sp li ds e
  setSpanInfo sp (Do _ li stms e)            = Do sp li stms e
  setSpanInfo sp (IfThenElse _ e1 e2 e3)     = IfThenElse sp e1 e2 e3
  setSpanInfo sp (Case _ li ct e as)         = Case sp li ct e as

instance HasSpanInfo (Statement a) where
  getSpanInfo (StmtExpr sp _)   = sp
  getSpanInfo (StmtDecl sp _ _) = sp
  getSpanInfo (StmtBind sp _ _) = sp

  setSpanInfo sp (StmtExpr _ ex)    = StmtExpr sp ex
  setSpanInfo sp (StmtDecl _ li ds) = StmtDecl sp li ds
  setSpanInfo sp (StmtBind _ p ex)  = StmtBind sp p ex

instance HasSpanInfo (Alt a) where
  getSpanInfo (Alt sp _ _) = sp
  setSpanInfo sp (Alt _ p rhs) = Alt sp p rhs

instance HasSpanInfo (Field a) where
    getSpanInfo (Field sp _ _) = sp
    setSpanInfo sp (Field _ qid a) = Field sp qid a