1 (* Title: Tools/Code/code_haskell.ML
2 Author: Florian Haftmann, TU Muenchen
4 Serializer for Haskell.
7 signature CODE_HASKELL =
10 val setup: theory -> theory
13 structure Code_Haskell : CODE_HASKELL =
16 val target = "Haskell";
18 open Basic_Code_Thingol;
25 (** Haskell serializer **)
27 fun print_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const
28 reserved deresolve contr_classparam_typs deriving_show =
30 val deresolve_base = Long_Name.base_name o deresolve;
31 fun class_name class = case syntax_class class
32 of NONE => deresolve class
33 | SOME class => class;
34 fun print_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs
36 | constraints => enum "," "(" ")" (
38 str (class_name class ^ " " ^ lookup_var tyvars v)) constraints)
40 fun print_typforall tyvars vs = case map fst vs
42 | vnames => str "forall " :: Pretty.breaks
43 (map (str o lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1;
44 fun print_tyco_expr tyvars fxy (tyco, tys) =
45 brackify fxy (str tyco :: map (print_typ tyvars BR) tys)
46 and print_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco
47 of NONE => print_tyco_expr tyvars fxy (deresolve tyco, tys)
48 | SOME (i, print) => print (print_typ tyvars) fxy tys)
49 | print_typ tyvars fxy (ITyVar v) = (str o lookup_var tyvars) v;
50 fun print_typdecl tyvars (vs, tycoexpr) =
51 Pretty.block (print_typcontext tyvars vs @| print_tyco_expr tyvars NOBR tycoexpr);
52 fun print_typscheme tyvars (vs, ty) =
53 Pretty.block (print_typforall tyvars vs @ print_typcontext tyvars vs @| print_typ tyvars NOBR ty);
54 fun print_term tyvars some_thm vars fxy (IConst c) =
55 print_app tyvars some_thm vars fxy (c, [])
56 | print_term tyvars some_thm vars fxy (t as (t1 `$ t2)) =
57 (case Code_Thingol.unfold_const_app t
58 of SOME app => print_app tyvars some_thm vars fxy app
61 print_term tyvars some_thm vars NOBR t1,
62 print_term tyvars some_thm vars BR t2
64 | print_term tyvars some_thm vars fxy (IVar NONE) =
66 | print_term tyvars some_thm vars fxy (IVar (SOME v)) =
67 (str o lookup_var vars) v
68 | print_term tyvars some_thm vars fxy (t as _ `|=> _) =
70 val (binds, t') = Code_Thingol.unfold_pat_abs t;
71 val (ps, vars') = fold_map (print_bind tyvars some_thm BR o fst) binds vars;
72 in brackets (str "\\" :: ps @ str "->" @@ print_term tyvars some_thm vars' NOBR t') end
73 | print_term tyvars some_thm vars fxy (ICase (cases as (_, t0))) =
74 (case Code_Thingol.unfold_const_app t0
75 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c)
76 then print_case tyvars some_thm vars fxy cases
77 else print_app tyvars some_thm vars fxy c_ts
78 | NONE => print_case tyvars some_thm vars fxy cases)
79 and print_app_expr tyvars some_thm vars ((c, (_, function_typs)), ts) = case contr_classparam_typs c
80 of [] => (str o deresolve) c :: map (print_term tyvars some_thm vars BR) ts
82 val ts_fingerprint = ts ~~ take (length ts) fingerprint;
83 val needs_annotation = forall (fn (_, NONE) => true | (t, SOME _) =>
84 (not o Code_Thingol.locally_monomorphic) t) ts_fingerprint;
85 fun print_term_anno (t, NONE) _ = print_term tyvars some_thm vars BR t
86 | print_term_anno (t, SOME _) ty =
87 brackets [print_term tyvars some_thm vars NOBR t, str "::", print_typ tyvars NOBR ty];
89 if needs_annotation then
90 (str o deresolve) c :: map2 print_term_anno ts_fingerprint (take (length ts) function_typs)
91 else (str o deresolve) c :: map (print_term tyvars some_thm vars BR) ts
93 and print_app tyvars = gen_print_app (print_app_expr tyvars) (print_term tyvars) syntax_const
94 and print_bind tyvars some_thm fxy p = gen_print_bind (print_term tyvars) some_thm fxy p
95 and print_case tyvars some_thm vars fxy (cases as ((_, [_]), _)) =
97 val (binds, body) = Code_Thingol.unfold_let (ICase cases);
98 fun print_match ((pat, ty), t) vars =
100 |> print_bind tyvars some_thm BR pat
101 |>> (fn p => semicolon [p, str "=", print_term tyvars some_thm vars NOBR t])
102 val (ps, vars') = fold_map print_match binds vars;
103 in brackify_block fxy (str "let {")
105 (concat [str "}", str "in", print_term tyvars some_thm vars' NOBR body])
107 | print_case tyvars some_thm vars fxy (((t, ty), clauses as _ :: _), _) =
109 fun print_select (pat, body) =
111 val (p, vars') = print_bind tyvars some_thm NOBR pat vars;
112 in semicolon [p, str "->", print_term tyvars some_thm vars' NOBR body] end;
113 in Pretty.block_enclose
114 (concat [str "(case", print_term tyvars some_thm vars NOBR t, str "of", str "{"], str "})")
115 (map print_select clauses)
117 | print_case tyvars some_thm vars fxy ((_, []), _) =
118 (brackify fxy o Pretty.breaks o map str) ["error", "\"empty case\""];
119 fun print_stmt (name, Code_Thingol.Fun (_, (((vs, ty), raw_eqs), _))) =
121 val tyvars = intro_vars (map fst vs) reserved;
124 (str o deresolve_base) name
125 :: map str (replicate n "_")
128 @@ (str o ML_Syntax.print_string
129 o Long_Name.base_name o Long_Name.qualifier) name
131 fun print_eqn ((ts, t), (some_thm, _)) =
133 val consts = fold Code_Thingol.add_constnames (t :: ts) [];
136 (is_none o syntax_const) deresolve consts
137 |> intro_vars ((fold o Code_Thingol.fold_varnames)
138 (insert (op =)) ts []);
141 (str o deresolve_base) name
142 :: map (print_term tyvars some_thm vars BR) ts
144 @@ print_term tyvars some_thm vars NOBR t
150 (str o suffix " ::" o deresolve_base) name,
151 print_typscheme tyvars (vs, ty)
153 :: (case filter (snd o snd) raw_eqs
154 of [] => [print_err ((length o fst o Code_Thingol.unfold_fun) ty)]
155 | eqs => map print_eqn eqs)
158 | print_stmt (name, Code_Thingol.Datatype (_, (vs, []))) =
160 val tyvars = intro_vars (map fst vs) reserved;
164 print_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs))
167 | print_stmt (name, Code_Thingol.Datatype (_, (vs, [((co, _), [ty])]))) =
169 val tyvars = intro_vars (map fst vs) reserved;
173 :: print_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs))
175 :: (str o deresolve_base) co
176 :: print_typ tyvars BR ty
177 :: (if deriving_show name then [str "deriving (Read, Show)"] else [])
180 | print_stmt (name, Code_Thingol.Datatype (_, (vs, co :: cos))) =
182 val tyvars = intro_vars (map fst vs) reserved;
183 fun print_co ((co, _), tys) =
185 (str o deresolve_base) co
186 :: map (print_typ tyvars BR) tys
191 :: print_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs))
194 :: map ((fn p => Pretty.block [str "| ", p]) o print_co) cos
195 @ (if deriving_show name then [str "deriving (Read, Show)"] else [])
198 | print_stmt (name, Code_Thingol.Class (_, (v, (super_classes, classparams)))) =
200 val tyvars = intro_vars [v] reserved;
201 fun print_classparam (classparam, ty) =
203 (str o deresolve_base) classparam,
205 print_typ tyvars NOBR ty
208 Pretty.block_enclose (
211 Pretty.block (print_typcontext tyvars [(v, map fst super_classes)]),
212 str (deresolve_base name ^ " " ^ lookup_var tyvars v),
216 ) (map print_classparam classparams)
218 | print_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, (classparam_instances, _)))) =
220 val tyvars = intro_vars (map fst vs) reserved;
221 fun requires_args classparam = case syntax_const classparam
223 | SOME (Code_Printer.Plain_const_syntax _) => 0
224 | SOME (Code_Printer.Complex_const_syntax (k,_ )) => k;
225 fun print_classparam_instance ((classparam, const), (thm, _)) =
226 case requires_args classparam
228 (str o deresolve_base) classparam,
230 print_app tyvars (SOME thm) reserved NOBR (const, [])
234 val (c, (_, tys)) = const;
235 val (vs, rhs) = (apfst o map) fst
236 (Code_Thingol.unfold_abs (Code_Thingol.eta_expand k (const, [])));
237 val s = if (is_some o syntax_const) c
238 then NONE else (SOME o Long_Name.base_name o deresolve) c;
240 |> intro_vars (map_filter I (s :: vs));
241 val lhs = IConst (classparam, (([], []), tys)) `$$ map IVar vs;
242 (*dictionaries are not relevant at this late stage*)
245 print_term tyvars (SOME thm) vars NOBR lhs,
247 print_term tyvars (SOME thm) vars NOBR rhs
251 Pretty.block_enclose (
254 Pretty.block (print_typcontext tyvars vs),
255 str (class_name class ^ " "),
256 print_typ tyvars BR (tyco `%% map (ITyVar o fst) vs),
260 ) (map print_classparam_instance classparam_instances)
264 fun haskell_program_of_program labelled_name module_name module_prefix reserved raw_module_alias program =
266 val module_alias = if is_some module_name then K module_name else raw_module_alias;
267 val reserved = Name.make_context reserved;
268 val mk_name_module = mk_name_module reserved module_prefix module_alias program;
269 fun add_stmt (name, (stmt, deps)) =
271 val (module_name, base) = dest_name name;
272 val module_name' = mk_name_module module_name;
273 val mk_name_stmt = yield_singleton Name.variants;
274 fun add_fun upper (nsp_fun, nsp_typ) =
276 val (base', nsp_fun') =
277 mk_name_stmt (if upper then first_upper base else base) nsp_fun
278 in (base', (nsp_fun', nsp_typ)) end;
279 fun add_typ (nsp_fun, nsp_typ) =
281 val (base', nsp_typ') = mk_name_stmt (first_upper base) nsp_typ
282 in (base', (nsp_fun, nsp_typ')) end;
283 val add_name = case stmt
284 of Code_Thingol.Fun (_, (_, SOME _)) => pair base
285 | Code_Thingol.Fun _ => add_fun false
286 | Code_Thingol.Datatype _ => add_typ
287 | Code_Thingol.Datatypecons _ => add_fun true
288 | Code_Thingol.Class _ => add_typ
289 | Code_Thingol.Classrel _ => pair base
290 | Code_Thingol.Classparam _ => add_fun false
291 | Code_Thingol.Classinst _ => pair base;
292 fun add_stmt' base' = case stmt
293 of Code_Thingol.Fun (_, (_, SOME _)) =>
295 | Code_Thingol.Datatypecons _ =>
296 cons (name, (Long_Name.append module_name' base', NONE))
297 | Code_Thingol.Classrel _ => I
298 | Code_Thingol.Classparam _ =>
299 cons (name, (Long_Name.append module_name' base', NONE))
300 | _ => cons (name, (Long_Name.append module_name' base', SOME stmt));
302 Symtab.map_default (module_name', ([], ([], (reserved, reserved))))
303 (apfst (fold (insert (op = : string * string -> bool)) deps))
304 #> `(fn program => add_name ((snd o snd o the o Symtab.lookup program) module_name'))
305 #-> (fn (base', names) =>
306 (Symtab.map_entry module_name' o apsnd) (fn (stmts, _) =>
307 (add_stmt' base' stmts, names)))
309 val hs_program = fold add_stmt (AList.make (fn name =>
310 (Graph.get_node program name, Graph.imm_succs program name))
311 (Graph.strong_conn program |> flat)) Symtab.empty;
312 fun deresolver name = (fst o the o AList.lookup (op =) ((fst o snd o the
313 o Symtab.lookup hs_program) ((mk_name_module o fst o dest_name) name))) name
314 handle Option => error ("Unknown statement name: " ^ labelled_name name);
315 in (deresolver, hs_program) end;
317 fun serialize_haskell module_prefix raw_module_name string_classes labelled_name
318 raw_reserved includes raw_module_alias
319 syntax_class syntax_tyco syntax_const (code_of_pretty, code_writeln) program stmt_names destination =
321 val presentation_stmt_names = Code_Target.stmt_names_of_destination destination;
322 val module_name = if null presentation_stmt_names then raw_module_name else SOME "Code";
323 val reserved = fold (insert (op =) o fst) includes raw_reserved;
324 val (deresolver, hs_program) = haskell_program_of_program labelled_name
325 module_name module_prefix reserved raw_module_alias program;
326 val contr_classparam_typs = Code_Thingol.contr_classparam_typs program;
327 fun deriving_show tyco =
329 fun deriv _ "fun" = false
330 | deriv tycos tyco = not (tyco = Code_Thingol.fun_tyco)
331 andalso (member (op =) tycos tyco
332 orelse case try (Graph.get_node program) tyco
333 of SOME (Code_Thingol.Datatype (_, (_, cs))) => forall (deriv' (tyco :: tycos))
336 and deriv' tycos (tyco `%% tys) = deriv tycos tyco
337 andalso forall (deriv' tycos) tys
338 | deriv' _ (ITyVar _) = true
339 in deriv [] tyco end;
340 val reserved = make_vars reserved;
341 fun print_stmt qualified = print_haskell_stmt labelled_name
342 syntax_class syntax_tyco syntax_const reserved
343 (if qualified then deresolver else Long_Name.base_name o deresolver)
344 contr_classparam_typs
345 (if string_classes then deriving_show else K false);
346 fun print_module name content =
347 (name, Pretty.chunks [
348 str ("module " ^ name ^ " where {"),
354 fun serialize_module1 (module_name', (deps, (stmts, _))) =
356 val stmt_names = map fst stmts;
357 val qualified = is_none module_name;
358 val imports = subtract (op =) stmt_names deps
360 |> map_filter (try deresolver)
361 |> map Long_Name.qualifier
363 fun print_import_include (name, _) = str ("import qualified " ^ name ^ ";");
364 fun print_import_module name = str ((if qualified
365 then "import qualified "
366 else "import ") ^ name ^ ";");
367 val import_ps = map print_import_include includes @ map print_import_module imports
368 val content = Pretty.chunks2 ((if null import_ps then [] else [Pretty.chunks import_ps])
370 (fn (name, (_, SOME stmt)) => SOME (print_stmt qualified (name, stmt))
371 | (_, (_, NONE)) => NONE) stmts
373 in print_module module_name' content end;
374 fun serialize_module2 (_, (_, (stmts, _))) = Pretty.chunks2 (map_filter
375 (fn (name, (_, SOME stmt)) => if null presentation_stmt_names
376 orelse member (op =) presentation_stmt_names name
377 then SOME (print_stmt false (name, stmt))
379 | (_, (_, NONE)) => NONE) stmts);
380 val serialize_module =
381 if null presentation_stmt_names then serialize_module1 else pair "" o serialize_module2;
382 fun check_destination destination =
383 (File.check destination; destination);
384 fun write_module destination (modlname, content) =
386 val filename = case modlname
387 of "" => Path.explode "Main.hs"
388 | _ => (Path.ext "hs" o Path.explode o implode o separate "/"
389 o Long_Name.explode) modlname;
390 val pathname = Path.append destination filename;
391 val _ = File.mkdir_leaf (Path.dir pathname);
392 in File.write pathname
393 ("{-# OPTIONS_GHC -fglasgow-exts #-}\n\n"
394 ^ code_of_pretty content)
397 Code_Target.mk_serialization target
398 (fn NONE => K () o map (code_writeln o snd) | SOME file => K () o map
399 (write_module (check_destination file)))
400 (rpair [] o cat_lines o map (code_of_pretty o snd))
401 (map (uncurry print_module) includes
402 @ map serialize_module (Symtab.dest hs_program))
409 val s = ML_Syntax.print_char c;
410 in if s = "'" then "\\'" else s end;
411 fun numeral_haskell k = if k >= 0 then string_of_int k
412 else Library.enclose "(" ")" (signed_string_of_int k);
414 literal_char = Library.enclose "'" "'" o char_haskell,
415 literal_string = quote o translate_string char_haskell,
416 literal_numeral = numeral_haskell,
417 literal_positive_numeral = numeral_haskell,
418 literal_alternative_numeral = numeral_haskell,
419 literal_naive_numeral = numeral_haskell,
420 literal_list = enum "," "[" "]",
421 infix_cons = (5, ":")
425 (** optional monad syntax **)
427 fun pretty_haskell_monad c_bind =
429 fun dest_bind t1 t2 = case Code_Thingol.split_pat_abs t2
430 of SOME ((pat, ty), t') =>
431 SOME ((SOME ((pat, ty), true), t1), t')
433 fun dest_monad c_bind_name (IConst (c, _) `$ t1 `$ t2) =
434 if c = c_bind_name then dest_bind t1 t2
436 | dest_monad _ t = case Code_Thingol.split_let t
437 of SOME (((pat, ty), tbind), t') =>
438 SOME ((SOME ((pat, ty), false), tbind), t')
440 fun implode_monad c_bind_name = Code_Thingol.unfoldr (dest_monad c_bind_name);
441 fun print_monad print_bind print_term (NONE, t) vars =
442 (semicolon [print_term vars NOBR t], vars)
443 | print_monad print_bind print_term (SOME ((bind, _), true), t) vars = vars
444 |> print_bind NOBR bind
445 |>> (fn p => semicolon [p, str "<-", print_term vars NOBR t])
446 | print_monad print_bind print_term (SOME ((bind, _), false), t) vars = vars
447 |> print_bind NOBR bind
448 |>> (fn p => semicolon [str "let", str "{", p, str "=", print_term vars NOBR t, str "}"]);
449 fun pretty _ [c_bind'] print_term thm vars fxy [(t1, _), (t2, _)] = case dest_bind t1 t2
450 of SOME (bind, t') => let
451 val (binds, t'') = implode_monad c_bind' t'
452 val (ps, vars') = fold_map (print_monad (gen_print_bind (K print_term) thm) print_term)
453 (bind :: binds) vars;
455 (brackify fxy o single o enclose "do { " " }" o Pretty.breaks)
456 (ps @| print_term vars' NOBR t'')
458 | NONE => brackify_infix (1, L) fxy
459 (print_term vars (INFX (1, L)) t1, str ">>=", print_term vars (INFX (1, X)) t2)
460 in (2, ([c_bind], pretty)) end;
462 fun add_monad target' raw_c_bind thy =
464 val c_bind = Code.read_const thy raw_c_bind;
465 in if target = target' then
467 |> Code_Target.add_syntax_const target c_bind
468 (SOME (Code_Printer.complex_const_syntax (pretty_haskell_monad c_bind)))
469 else error "Only Haskell target allows for monad syntax" end;
474 fun isar_serializer module_name =
475 Code_Target.parse_args (Scan.option (Args.$$$ "root" -- Args.colon |-- Args.name)
476 -- Scan.optional (Args.$$$ "string_classes" >> K true) false
477 >> (fn (module_prefix, string_classes) =>
478 serialize_haskell module_prefix module_name string_classes));
481 Outer_Syntax.command "code_monad" "define code syntax for monads" Keyword.thy_decl (
482 Parse.term_group -- Parse.name >> (fn (raw_bind, target) =>
483 Toplevel.theory (add_monad target raw_bind))
487 Code_Target.add_target
488 (target, { serializer = isar_serializer, literals = literals,
489 check = { env_var = "EXEC_GHC", make_destination = I,
490 make_command = fn ghc => fn p => fn module_name =>
491 ghc ^ " -fglasgow-exts -odir build -hidir build -stubdir build -e \"\" " ^ module_name ^ ".hs" } })
492 #> Code_Target.add_syntax_tyco target "fun" (SOME (2, fn print_typ => fn fxy => fn [ty1, ty2] =>
493 brackify_infix (1, R) fxy (
494 print_typ (INFX (1, X)) ty1,
496 print_typ (INFX (1, R)) ty2
498 #> fold (Code_Target.add_reserved target) [
499 "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
500 "import", "default", "forall", "let", "in", "class", "qualified", "data",
501 "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
503 #> fold (Code_Target.add_reserved target) [
504 "Prelude", "Main", "Bool", "Maybe", "Either", "Ordering", "Char", "String", "Int",
505 "Integer", "Float", "Double", "Rational", "IO", "Eq", "Ord", "Enum", "Bounded",
506 "Num", "Real", "Integral", "Fractional", "Floating", "RealFloat", "Monad", "Functor",
507 "AlreadyExists", "ArithException", "ArrayException", "AssertionFailed", "AsyncException",
508 "BlockedOnDeadMVar", "Deadlock", "Denormal", "DivideByZero", "DotNetException", "DynException",
509 "Dynamic", "EOF", "EQ", "EmptyRec", "ErrorCall", "ExitException", "ExitFailure",
510 "ExitSuccess", "False", "GT", "HeapOverflow",
511 "IOError", "IOException", "IllegalOperation",
512 "IndexOutOfBounds", "Just", "Key", "LT", "Left", "LossOfPrecision", "NoMethodError",
513 "NoSuchThing", "NonTermination", "Nothing", "Obj", "OtherError", "Overflow",
514 "PatternMatchFail", "PermissionDenied", "ProtocolError", "RecConError", "RecSelError",
515 "RecUpdError", "ResourceBusy", "ResourceExhausted", "Right", "StackOverflow",
516 "ThreadKilled", "True", "TyCon", "TypeRep", "UndefinedElement", "Underflow",
517 "UnsupportedOperation", "UserError", "abs", "absReal", "acos", "acosh", "all",
518 "and", "any", "appendFile", "asTypeOf", "asciiTab", "asin", "asinh", "atan",
519 "atan2", "atanh", "basicIORun", "blockIO", "boundedEnumFrom", "boundedEnumFromThen",
520 "boundedEnumFromThenTo", "boundedEnumFromTo", "boundedPred", "boundedSucc", "break",
521 "catch", "catchException", "ceiling", "compare", "concat", "concatMap", "const",
522 "cos", "cosh", "curry", "cycle", "decodeFloat", "denominator", "div", "divMod",
523 "doubleToRatio", "doubleToRational", "drop", "dropWhile", "either", "elem",
524 "emptyRec", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo",
525 "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter", "flip",
526 "floatDigits", "floatProperFraction", "floatRadix", "floatRange", "floatToRational",
527 "floor", "fmap", "foldl", "foldl'", "foldl1", "foldr", "foldr1", "fromDouble",
528 "fromEnum", "fromEnum_0", "fromInt", "fromInteger", "fromIntegral", "fromObj",
529 "fromRational", "fst", "gcd", "getChar", "getContents", "getLine", "head",
530 "id", "inRange", "index", "init", "intToRatio", "interact", "ioError", "isAlpha",
531 "isAlphaNum", "isDenormalized", "isDigit", "isHexDigit", "isIEEE", "isInfinite",
532 "isLower", "isNaN", "isNegativeZero", "isOctDigit", "isSpace", "isUpper", "iterate", "iterate'",
533 "last", "lcm", "length", "lex", "lexDigits", "lexLitChar", "lexmatch", "lines", "log",
534 "logBase", "lookup", "loop", "map", "mapM", "mapM_", "max", "maxBound", "maximum",
535 "maybe", "min", "minBound", "minimum", "mod", "negate", "nonnull", "not", "notElem",
536 "null", "numerator", "numericEnumFrom", "numericEnumFromThen", "numericEnumFromThenTo",
537 "numericEnumFromTo", "odd", "or", "otherwise", "pi", "pred",
538 "print", "product", "properFraction", "protectEsc", "putChar", "putStr", "putStrLn",
539 "quot", "quotRem", "range", "rangeSize", "rationalToDouble", "rationalToFloat",
540 "rationalToRealFloat", "read", "readDec", "readField", "readFieldName", "readFile",
541 "readFloat", "readHex", "readIO", "readInt", "readList", "readLitChar", "readLn",
542 "readOct", "readParen", "readSigned", "reads", "readsPrec", "realFloatToRational",
543 "realToFrac", "recip", "reduce", "rem", "repeat", "replicate", "return", "reverse",
544 "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq", "sequence",
545 "sequence_", "show", "showChar", "showException", "showField", "showList",
546 "showLitChar", "showParen", "showString", "shows", "showsPrec", "significand",
547 "signum", "signumReal", "sin", "sinh", "snd", "span", "splitAt", "sqrt", "subtract",
548 "succ", "sum", "tail", "take", "takeWhile", "takeWhile1", "tan", "tanh", "threadToIOResult",
549 "throw", "toEnum", "toInt", "toInteger", "toObj", "toRational", "truncate", "uncurry",
550 "undefined", "unlines", "unsafeCoerce", "unsafeIndex", "unsafeRangeSize", "until", "unwords",
551 "unzip", "unzip3", "userError", "words", "writeFile", "zip", "zip3", "zipWith", "zipWith3"
552 ] (*due to weird handling of ':', we can't do anything else than to import *all* prelude symbols*);