merged
authorhaftmann
Wed, 30 Jun 2010 11:39:10 +0200
changeset 37641 39bd6f7c25c2
parent 37637 ade245a81481 (current diff)
parent 37640 fc27be4c6b1c (diff)
child 37644 48bdc2a43b46
child 37651 62fc16341922
merged
--- a/src/Tools/Code/code_printer.ML	Tue Jun 29 22:59:29 2010 +0200
+++ b/src/Tools/Code/code_printer.ML	Wed Jun 30 11:39:10 2010 +0200
@@ -63,7 +63,7 @@
   val brackify: fixity -> Pretty.T list -> Pretty.T
   val brackify_infix: int * lrx -> fixity -> Pretty.T * Pretty.T * Pretty.T -> Pretty.T
   val brackify_block: fixity -> Pretty.T -> Pretty.T list -> Pretty.T -> Pretty.T
-  val applify: string -> string -> fixity -> Pretty.T -> Pretty.T list -> Pretty.T
+  val applify: string -> string -> ('a -> Pretty.T) -> fixity -> Pretty.T -> 'a list -> Pretty.T
 
   type tyco_syntax
   type simple_const_syntax
@@ -230,10 +230,10 @@
     else p
   end;
 
-fun applify opn cls fxy_ctxt p [] = p
-  | applify opn cls fxy_ctxt p ps =
+fun applify opn cls f fxy_ctxt p [] = p
+  | applify opn cls f fxy_ctxt p ps =
       (if (fixity BR fxy_ctxt) then enclose "(" ")" else Pretty.block)
-        (p @@ enum "," opn cls ps);
+        (p @@ enum "," opn cls (map f ps));
 
 
 (* generic syntax *)
--- a/src/Tools/Code/code_scala.ML	Tue Jun 29 22:59:29 2010 +0200
+++ b/src/Tools/Code/code_scala.ML	Wed Jun 30 11:39:10 2010 +0200
@@ -23,17 +23,26 @@
 (** Scala serializer **)
 
 fun print_scala_stmt labelled_name syntax_tyco syntax_const reserved
-    args_num is_singleton deresolve =
+    args_num is_singleton_constr deresolve =
   let
     val deresolve_base = Long_Name.base_name o deresolve;
-    val lookup_tyvar = first_upper oo lookup_var;
-    fun print_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco
-         of NONE => applify "[" "]" fxy
-              ((str o deresolve) tyco) (map (print_typ tyvars NOBR) tys)
+    fun lookup_tyvar tyvars = lookup_var tyvars o first_upper;
+    fun intro_tyvars vs = intro_vars (map (first_upper o fst) vs);
+    fun print_tyco_expr tyvars fxy (tyco, tys) = applify "[" "]"
+          (print_typ tyvars NOBR) fxy ((str o deresolve) tyco) tys
+    and print_typ tyvars fxy (tyco `%% tys) = (case syntax_tyco tyco
+         of NONE => print_tyco_expr tyvars fxy (tyco, tys)
           | SOME (i, print) => print (print_typ tyvars) fxy tys)
       | print_typ tyvars fxy (ITyVar v) = (str o lookup_tyvar tyvars) v;
-    fun print_typed tyvars p ty =
-      Pretty.block [p, str ":", Pretty.brk 1, print_typ tyvars NOBR ty]
+    fun print_dicttyp tyvars (class, ty) = print_tyco_expr tyvars NOBR (class, [ty]);
+    fun print_tupled_typ tyvars ([], ty) =
+          print_typ tyvars NOBR ty
+      | print_tupled_typ tyvars ([ty1], ty2) =
+          concat [print_typ tyvars BR ty1, str "=>", print_typ tyvars NOBR ty2]
+      | print_tupled_typ tyvars (tys, ty) =
+          concat [enum "," "(" ")" (map (print_typ tyvars NOBR) tys),
+            str "=>", print_typ tyvars NOBR ty];
+    fun constraint p1 p2 = Pretty.block [p1, str ":", Pretty.brk 1, p2];
     fun print_var vars NONE = str "_"
       | print_var vars (SOME v) = (str o lookup_var vars) v
     fun print_term tyvars is_pat some_thm vars fxy (IConst c) =
@@ -41,9 +50,8 @@
       | print_term tyvars is_pat some_thm vars fxy (t as (t1 `$ t2)) =
           (case Code_Thingol.unfold_const_app t
            of SOME app => print_app tyvars is_pat some_thm vars fxy app
-            | _ => applify "(" ")" fxy
-                (print_term tyvars is_pat some_thm vars BR t1)
-                [print_term tyvars is_pat some_thm vars NOBR t2])
+            | _ => applify "(" ")" (print_term tyvars is_pat some_thm vars NOBR) fxy
+                (print_term tyvars is_pat some_thm vars BR t1) [t2])
       | print_term tyvars is_pat some_thm vars fxy (IVar v) =
           print_var vars v
       | print_term tyvars is_pat some_thm vars fxy ((v, ty) `|=> t) =
@@ -51,7 +59,7 @@
             val vars' = intro_vars (the_list v) vars;
           in
             concat [
-              Pretty.block [str "(", print_typed tyvars (print_var vars' v) ty, str ")"],
+              enclose "(" ")" [constraint (print_var vars' v) (print_typ tyvars NOBR ty)],
               str "=>",
               print_term tyvars false some_thm vars' NOBR t
             ]
@@ -68,12 +76,12 @@
         val k = length ts;
         val l = case syntax_const c of NONE => args_num c | SOME (l, _) => l;
         val arg_typs' = if is_pat orelse
-          (is_none (syntax_const c) andalso is_singleton c) then [] else arg_typs;
+          (is_none (syntax_const c) andalso is_singleton_constr c) then [] else arg_typs;
         val (no_syntax, print') = case syntax_const c
-         of NONE => (true, fn ts => applify "(" ")" fxy
-              (applify "[" "]" NOBR ((str o deresolve) c)
-                (map (print_typ tyvars NOBR) arg_typs'))
-                  (map (print_term tyvars is_pat some_thm vars NOBR) ts))
+         of NONE => (true, fn ts => applify "(" ")"
+              (print_term tyvars is_pat some_thm vars NOBR) fxy
+                (applify "[" "]" (print_typ tyvars NOBR)
+                  NOBR ((str o deresolve) c) arg_typs') ts)
           | SOME (_, print) => (false, fn ts =>
               print (print_term tyvars is_pat some_thm) some_thm vars fxy
                 (ts ~~ take l function_typs));
@@ -94,15 +102,14 @@
             fun print_match ((pat, ty), t) vars =
               vars
               |> print_bind tyvars some_thm BR pat
-              |>> (fn p => semicolon [Pretty.block [str "val", Pretty.brk 1, p,
-                str ":", Pretty.brk 1, print_typ tyvars NOBR ty],
+              |>> (fn p => concat [str "val", constraint p (print_typ tyvars NOBR ty),
                   str "=", print_term tyvars false some_thm vars NOBR t])
-            val (ps, vars') = fold_map print_match binds vars;
-          in
-            brackify_block fxy
-              (str "{")
-              (ps @| print_term tyvars false some_thm vars' NOBR body)
-              (str "}")
+            val (all_ps, vars') = fold_map print_match binds vars;
+            val (ps, p) = split_last all_ps;
+          in brackify_block fxy
+            (str "{")
+            (ps @ Pretty.block [p, str ";"] @@ print_term tyvars false some_thm vars' NOBR body)
+            (str "}")
           end
       | print_case tyvars some_thm vars fxy (((t, ty), clauses as _ :: _), _) =
           let
@@ -118,156 +125,124 @@
           end
       | print_case tyvars some_thm vars fxy ((_, []), _) =
           (brackify fxy o Pretty.breaks o map str) ["error(\"empty case\")"];
-    fun print_defhead tyvars vars p vs params tys implicits (*FIXME simplify*) ty =
-      Pretty.block [str "def ", print_typed tyvars (applify "(implicit " ")" NOBR
-        (applify "(" ")" NOBR
-          (applify "[" "]" NOBR p (map (fn (v, sort) =>
-              (str o implode)
-                (lookup_tyvar tyvars v :: map (prefix ": " o deresolve) sort)) vs))
-            (map2 (fn param => fn ty => print_typed tyvars
-                ((str o lookup_var vars) param) ty)
-              params tys)) implicits) ty, str " ="]
-    fun print_stmt (name, Code_Thingol.Fun (_, (((vs, ty), raw_eqs), _))) =
-        (case filter (snd o snd) raw_eqs
-         of [] =>
-              let
-                val (tys, ty') = Code_Thingol.unfold_fun ty;
-                val params = Name.invents (snd reserved) "a" (length tys);
-                val tyvars = intro_vars (map fst vs) reserved;
-                val vars = intro_vars params reserved;
-              in
-                concat [print_defhead tyvars vars ((str o deresolve) name) vs params tys [] ty',
-                  str ("error(\"" ^ name ^ "\")")]
-              end
-          | eqs =>
+    fun print_context tyvars vs name = applify "[" "]"
+      (fn (v, sort) => (Pretty.block o map str)
+        (lookup_tyvar tyvars v :: maps (fn sort => [": ", deresolve sort]) sort))
+          NOBR ((str o deresolve) name) vs;
+    fun print_defhead tyvars vars name vs params tys ty =
+      Pretty.block [str "def ", constraint (applify "(" ")" (fn (param, ty) =>
+        constraint ((str o lookup_var vars) param) (print_typ tyvars NOBR ty))
+          NOBR (print_context tyvars vs name) (params ~~ tys)) (print_typ tyvars NOBR ty),
+            str " ="];
+    fun print_def name (vs, ty) [] =
+          let
+            val (tys, ty') = Code_Thingol.unfold_fun ty;
+            val params = Name.invents (snd reserved) "a" (length tys);
+            val tyvars = intro_tyvars vs reserved;
+            val vars = intro_vars params reserved;
+          in
+            concat [print_defhead tyvars vars name vs params tys ty',
+              str ("error(\"" ^ name ^ "\")")]
+          end
+      | print_def name (vs, ty) eqs =
+          let
+            val tycos = fold (fn ((ts, t), _) =>
+              fold Code_Thingol.add_tyconames (t :: ts)) eqs [];
+            val tyvars = reserved
+              |> intro_base_names
+                   (is_none o syntax_tyco) deresolve tycos
+              |> intro_tyvars vs;
+            val simple = case eqs
+             of [((ts, _), _)] => forall Code_Thingol.is_IVar ts
+              | _ => false;
+            val consts = fold Code_Thingol.add_constnames
+              (map (snd o fst) eqs) [];
+            val vars1 = reserved
+              |> intro_base_names
+                   (is_none o syntax_const) deresolve consts
+            val params = if simple
+              then (map (fn IVar (SOME x) => x) o fst o fst o hd) eqs
+              else aux_params vars1 (map (fst o fst) eqs);
+            val vars2 = intro_vars params vars1;
+            val (tys', ty') = Code_Thingol.unfold_fun_n (length params) ty;
+            fun print_tuple [p] = p
+              | print_tuple ps = enum "," "(" ")" ps;
+            fun print_rhs vars' ((_, t), (some_thm, _)) =
+              print_term tyvars false some_thm vars' NOBR t;
+            fun print_clause (eq as ((ts, _), (some_thm, _))) =
               let
-                val tycos = fold (fn ((ts, t), _) =>
-                  fold Code_Thingol.add_tyconames (t :: ts)) eqs [];
-                val tyvars = reserved
-                  |> intro_base_names
-                       (is_none o syntax_tyco) deresolve tycos
-                  |> intro_vars (map fst vs);
-                val simple = case eqs
-                 of [((ts, _), _)] => forall Code_Thingol.is_IVar ts
-                  | _ => false;
-                val consts = fold Code_Thingol.add_constnames
-                  (map (snd o fst) eqs) [];
-                val vars1 = reserved
-                  |> intro_base_names
-                       (is_none o syntax_const) deresolve consts
-                val params = if simple
-                  then (map (fn IVar (SOME x) => x) o fst o fst o hd) eqs
-                  else aux_params vars1 (map (fst o fst) eqs);
-                val vars2 = intro_vars params vars1;
-                val (tys, ty1) = Code_Thingol.unfold_fun ty;
-                val (tys1, tys2) = chop (length params) tys;
-                val ty2 = Library.foldr
-                  (fn (ty1, ty2) => Code_Thingol.fun_tyco `%% [ty1, ty2]) (tys2, ty1);
-                fun print_tuple [p] = p
-                  | print_tuple ps = enum "," "(" ")" ps;
-                fun print_rhs vars' ((_, t), (some_thm, _)) =
-                  print_term tyvars false some_thm vars' NOBR t;
-                fun print_clause (eq as ((ts, _), (some_thm, _))) =
-                  let
-                    val vars' = intro_vars ((fold o Code_Thingol.fold_varnames)
-                      (insert (op =)) ts []) vars1;
-                  in
-                    concat [str "case",
-                      print_tuple (map (print_term tyvars true some_thm vars' NOBR) ts),
-                      str "=>", print_rhs vars' eq]
-                  end;
-                val head = print_defhead tyvars vars2 ((str o deresolve) name) vs params tys1 [] ty2;
-              in if simple then
-                concat [head, print_rhs vars2 (hd eqs)]
-              else
-                Pretty.block_enclose
-                  (concat [head, print_tuple (map (str o lookup_var vars2) params),
-                    str "match", str "{"], str "}")
-                  (map print_clause eqs)
-              end)
+                val vars' = intro_vars ((fold o Code_Thingol.fold_varnames)
+                  (insert (op =)) ts []) vars1;
+              in
+                concat [str "case",
+                  print_tuple (map (print_term tyvars true some_thm vars' NOBR) ts),
+                  str "=>", print_rhs vars' eq]
+              end;
+            val head = print_defhead tyvars vars2 name vs params tys' ty';
+          in if simple then
+            concat [head, print_rhs vars2 (hd eqs)]
+          else
+            Pretty.block_enclose
+              (concat [head, print_tuple (map (str o lookup_var vars2) params),
+                str "match", str "{"], str "}")
+              (map print_clause eqs)
+          end;
+    val print_method = (str o Library.enclose "`" "+`" o deresolve_base);
+    fun print_stmt (name, Code_Thingol.Fun (_, (((vs, ty), raw_eqs), _))) =
+          print_def name (vs, ty) (filter (snd o snd) raw_eqs)
       | print_stmt (name, Code_Thingol.Datatype (_, (vs, cos))) =
           let
-            val tyvars = intro_vars (map fst vs) reserved;
+            val tyvars = intro_tyvars vs reserved;
             fun print_co ((co, _), []) =
                   concat [str "final", str "case", str "object", (str o deresolve_base) co,
-                    str "extends", applify "[" "]" NOBR ((str o deresolve_base) name)
+                    str "extends", applify "[" "]" I NOBR ((str o deresolve_base) name)
                       (replicate (length vs) (str "Nothing"))]
               | print_co ((co, vs_args), tys) =
-                  let
-                    val fields = Name.names (snd reserved) "a" tys;
-                    val vars = intro_vars (map fst fields) reserved;
-                    fun add_typargs1 p = applify "[" "]" NOBR p
-                      (map (str o lookup_tyvar tyvars o fst) vs); (*FIXME*)
-                    fun add_typargs2 p = applify "[" "]" NOBR p
-                      (map (str o lookup_tyvar tyvars) vs_args); (*FIXME*)
-                  in
-                    concat [
-                      applify "(" ")" NOBR
-                        (add_typargs2 ((concat o map str)
-                          ["final", "case", "class", deresolve_base co]))
-                        (map (uncurry (print_typed tyvars) o apfst str) fields),
-                      str "extends",
-                      add_typargs1 ((str o deresolve_base) name)
-                    ]
-                  end
+                  concat [applify "(" ")"
+                    (fn (v, arg) => constraint (str v) (print_typ tyvars NOBR arg)) NOBR
+                    (applify "[" "]" (str o lookup_tyvar tyvars) NOBR ((concat o map str)
+                      ["final", "case", "class", deresolve_base co]) vs_args)
+                    (Name.names (snd reserved) "a" tys),
+                    str "extends",
+                    applify "[" "]" (str o lookup_tyvar tyvars o fst) NOBR
+                      ((str o deresolve_base) name) vs
+                  ];
           in
-            Pretty.chunks (
-              applify "[" "]" NOBR ((concat o map str)
-                  ["sealed", "class", deresolve_base name])
-                (map (str o prefix "+" o lookup_tyvar tyvars o fst) vs)
-              :: map print_co cos
-            )
+            Pretty.chunks (applify "[" "]" (str o prefix "+" o lookup_tyvar tyvars o fst)
+              NOBR ((concat o map str) ["sealed", "class", deresolve_base name]) vs
+                :: map print_co cos)
           end
       | print_stmt (name, Code_Thingol.Class (_, (v, (super_classes, classparams)))) =
           let
-            val tyvars = intro_vars [v] reserved;
-            val vs = [(v, [name])];
-            fun add_typarg p = applify "[" "]" NOBR p [(str o lookup_tyvar tyvars) v];
+            val tyvars = intro_tyvars [(v, [name])] reserved;
+            fun add_typarg s = Pretty.block
+              [str s, str "[", (str o lookup_tyvar tyvars) v, str "]"];
             fun print_super_classes [] = NONE
               | print_super_classes classes = SOME (concat (str "extends"
-                  :: separate (str "with")
-                    (map (add_typarg o str o deresolve o fst) classes)));
-            fun print_tupled_typ ([], ty) =
-                  print_typ tyvars NOBR ty
-              | print_tupled_typ ([ty1], ty2) =
-                  concat [print_typ tyvars BR ty1, str "=>", print_typ tyvars NOBR ty2]
-              | print_tupled_typ (tys, ty) =
-                  concat [enum "," "(" ")" (map (print_typ tyvars NOBR) tys),
-                    str "=>", print_typ tyvars NOBR ty];
+                  :: separate (str "with") (map (add_typarg o deresolve o fst) classes)));
             fun print_classparam_val (classparam, ty) =
-              concat [str "val", (str o Library.enclose "`" "+`:" o deresolve_base)
-                  classparam,
-                (print_tupled_typ o Code_Thingol.unfold_fun) ty]
-            fun implicit_arguments tyvars vs vars = (*FIXME simplifiy*)
-              let
-                val implicit_typ_ps = maps (fn (v, sort) => map (fn class => Pretty.block
-                  [(str o deresolve) class, str "[",
-                    (str o lookup_tyvar tyvars) v, str "]"]) sort) vs;
-                val implicit_names = Name.variant_list [] (maps (fn (v, sort) =>
-                  map (fn class => lookup_tyvar tyvars v ^ "_" ^
-                    (Long_Name.base_name o deresolve) class) sort) vs);
-                val vars' = intro_vars implicit_names vars;
-                val implicit_ps = map2 (fn v => fn p => concat [str (v ^ ":"), p])
-                  implicit_names implicit_typ_ps;
-              in ((implicit_names, implicit_ps), vars') end;
+              concat [str "val", constraint (print_method classparam)
+                ((print_tupled_typ tyvars o Code_Thingol.unfold_fun) ty)];
             fun print_classparam_def (classparam, ty) =
               let
                 val (tys, ty) = Code_Thingol.unfold_fun ty;
-                val params = Name.invents (snd reserved) "a" (length tys);
-                val vars = intro_vars params reserved;
-                val (([implicit], [p_implicit]), vars') = implicit_arguments tyvars vs vars;
-                val head = print_defhead tyvars vars' ((str o deresolve) classparam)
-                  ((map o apsnd) (K []) vs) params tys [p_implicit] ty;
+                val [implicit_name] = Name.invents (snd reserved) (lookup_tyvar tyvars v) 1;
+                val proto_vars = intro_vars [implicit_name] reserved;
+                val auxs = Name.invents (snd proto_vars) "a" (length tys);
+                val vars = intro_vars auxs proto_vars;
               in
-                concat [head, applify "(" ")" NOBR
-                  (Pretty.block [str implicit, str ".",
-                    (str o Library.enclose "`" "+`" o deresolve_base) classparam])
-                  (map (str o lookup_var vars') params)]
+                concat [str "def", constraint (Pretty.block [applify "(" ")"
+                  (fn (aux, ty) => constraint ((str o lookup_var vars) aux)
+                  (print_typ tyvars NOBR ty)) NOBR (add_typarg (deresolve classparam))
+                  (auxs ~~ tys), str "(implicit ", str implicit_name, str ": ",
+                  add_typarg (deresolve name), str ")"]) (print_typ tyvars NOBR ty), str "=",
+                  applify "(" ")" (str o lookup_var vars) NOBR
+                  (Pretty.block [str implicit_name, str ".", print_method classparam]) auxs]
               end;
           in
             Pretty.chunks (
               (Pretty.block_enclose
-                (concat ([str "trait", add_typarg ((str o deresolve_base) name)]
+                (concat ([str "trait", (add_typarg o deresolve_base) name]
                   @ the_list (print_super_classes super_classes) @ [str "{"]), str "}")
                 (map print_classparam_val classparams))
               :: map print_classparam_def classparams
@@ -276,35 +251,27 @@
       | print_stmt (name, Code_Thingol.Classinst ((class, (tyco, vs)),
             (super_instances, (classparam_instances, further_classparam_instances)))) =
           let
-            val tyvars = intro_vars (map fst vs) reserved;
-            val classtyp = (class, (tyco, map fst vs));
-            fun print_classtyp' (class, (tyco, vs)) = (*FIXME already exists?*)
-              applify "[" "]" NOBR(*? FIXME*) ((str o deresolve) class)
-                [print_typ tyvars NOBR (tyco `%% map ITyVar vs)]; (*FIXME a mess...*)
-            fun print_typed' tyvars p classtyp = (*FIXME unify with existing print_typed*)
-              Pretty.block [p, str ":", Pretty.brk 1, print_classtyp' classtyp];
-            fun print_defhead' tyvars vars p vs params tys classtyp = (*FIXME unify with existing def_head*)
-              Pretty.block [str "def ", print_typed' tyvars
-                (applify "(" ")" NOBR
-                  (applify "[" "]" NOBR p (map (fn (v, sort) =>
-                      (str o implode) (lookup_tyvar tyvars v :: map (prefix ": " o deresolve) sort)) vs))
-                    (map2 (fn param => fn ty => print_typed tyvars ((str o lookup_var vars) param) ty)
-                      params tys)) classtyp, str " ="];
+            val tyvars = intro_tyvars vs reserved;
+            val classtyp = (class, tyco `%% map (ITyVar o fst) vs);
             fun print_classparam_instance ((classparam, const as (_, (_, tys))), (thm, _)) =
               let
-                val auxs = Name.invents (snd reserved) "a" (length tys);
+                val aux_tys = Name.names (snd reserved) "a" tys;
+                val auxs = map fst aux_tys;
                 val vars = intro_vars auxs reserved;
-                val args = if null auxs then [] else
-                  [concat [enum "," "(" ")" (map2 (fn aux => fn ty => print_typed tyvars ((str o lookup_var vars) aux) ty)
-                    auxs tys), str "=>"]];
+                val aux_abstr = if null auxs then [] else [enum "," "(" ")"
+                  (map (fn (aux, ty) => constraint ((str o lookup_var vars) aux)
+                  (print_typ tyvars NOBR ty)) aux_tys), str "=>"];
               in 
-                concat ([str "val", (str o Library.enclose "`" "+`" o deresolve_base) classparam,
-                  str "="] @ args @ [print_app tyvars false (SOME thm) vars NOBR (const, map (IVar o SOME) auxs)])
+                concat ([str "val", print_method classparam, str "="]
+                  @ aux_abstr @| print_app tyvars false (SOME thm) vars NOBR
+                    (const, map (IVar o SOME) auxs))
               end;
-            val head = print_defhead' tyvars reserved ((str o deresolve) name) vs [] [] classtyp;
-            val body = [str "new", print_classtyp' classtyp,
-              Pretty.enum ";" "{ " " }" (map print_classparam_instance (classparam_instances @ further_classparam_instances))];
-          in concat (str "implicit" :: head :: body) end;
+          in
+            Pretty.block_enclose (concat [str "implicit def",
+              constraint (print_context tyvars vs name) (print_dicttyp tyvars classtyp),
+              str "=", str "new", print_dicttyp tyvars classtyp, str "{"], str "}")
+                (map print_classparam_instance (classparam_instances @ further_classparam_instances))
+          end;
   in print_stmt end;
 
 fun scala_program_of_program labelled_name module_name reserved raw_module_alias program =
@@ -368,25 +335,24 @@
     val (deresolver, (the_module_name, sca_program)) = scala_program_of_program labelled_name
       module_name reserved raw_module_alias program;
     val reserved = make_vars reserved;
+    fun lookup_constr tyco constr = case Graph.get_node program tyco
+     of Code_Thingol.Datatype (_, (_, constrs)) =>
+          the (AList.lookup (op = o apsnd fst) constrs constr);
+    fun classparams_of_class class = case Graph.get_node program class
+     of Code_Thingol.Class (_, (_, (_, classparams))) => classparams;
     fun args_num c = case Graph.get_node program c
      of Code_Thingol.Fun (_, (((_, ty), []), _)) =>
           (length o fst o Code_Thingol.unfold_fun) ty
       | Code_Thingol.Fun (_, ((_, ((ts, _), _) :: _), _)) => length ts
-      | Code_Thingol.Datatypecons (_, tyco) =>
-          let val Code_Thingol.Datatype (_, (_, constrs)) = Graph.get_node program tyco
-          in (length o the o AList.lookup (eq_fst op =) constrs) (c, []) end (*FIXME simplify lookup*)
+      | Code_Thingol.Datatypecons (_, tyco) => length (lookup_constr tyco c)
       | Code_Thingol.Classparam (_, class) =>
-          let
-            val Code_Thingol.Class (_, (_, (_, classparams))) =
-              Graph.get_node program class
-          in (length o fst o Code_Thingol.unfold_fun o the o AList.lookup (op =) classparams) c end;
-    fun is_singleton c = case Graph.get_node program c
-     of Code_Thingol.Datatypecons (_, tyco) =>
-          let val Code_Thingol.Datatype (_, (_, constrs)) = Graph.get_node program tyco
-          in (null o the o AList.lookup (eq_fst op =) constrs) (c, []) end (*FIXME simplify lookup*)
+          (length o fst o Code_Thingol.unfold_fun o the o AList.lookup (op =)
+            (classparams_of_class class)) c;
+    fun is_singleton_constr c = case Graph.get_node program c
+     of Code_Thingol.Datatypecons (_, tyco) => null (lookup_constr tyco c)
       | _ => false;
     val print_stmt = print_scala_stmt labelled_name syntax_tyco syntax_const
-      reserved args_num is_singleton deresolver;
+      reserved args_num is_singleton_constr deresolver;
     fun print_module name content =
       (name, Pretty.chunks [
         str ("object " ^ name ^ " {"),
@@ -468,7 +434,7 @@
       "true", "type", "val", "var", "while", "with", "yield"
     ]
   #> fold (Code_Target.add_reserved target) [
-      "error", "apply", "List", "Nil", "BigInt"
+      "apply", "error", "BigInt", "Nil", "List"
     ];
 
 end; (*struct*)
--- a/src/Tools/Code/code_thingol.ML	Tue Jun 29 22:59:29 2010 +0200
+++ b/src/Tools/Code/code_thingol.ML	Wed Jun 30 11:39:10 2010 +0200
@@ -40,6 +40,7 @@
   val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list
   val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a
   val unfold_fun: itype -> itype list * itype
+  val unfold_fun_n: int -> itype -> itype list * itype
   val unfold_app: iterm -> iterm * iterm list
   val unfold_abs: iterm -> (vname option * itype) list * iterm
   val split_let: iterm -> (((iterm * itype) * iterm) * iterm) option
@@ -396,6 +397,13 @@
   (fn tyco `%% [ty1, ty2] => if tyco = fun_tyco then SOME (ty1, ty2) else NONE
     | _ => NONE);
 
+fun unfold_fun_n n ty =
+  let
+    val (tys1, ty1) = unfold_fun ty;
+    val (tys3, tys2) = chop n tys1;
+    val ty3 = Library.foldr (fn (ty1, ty2) => fun_tyco `%% [ty1, ty2]) (tys2, ty1);
+  in (tys3, ty3) end;
+
 end; (* local *)