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