anchor.diff:    | 3 -> List.mem (Ident.text_of_id op) [".()<-" ; ".[]<-"]
     | _ -> false
   
  +
  +// Style choice for type signatures. Depending on available space, they
  +// can be printed in one of three ways:
  +//   (1) all on the same line
  +//   (2) all on the same line, except the computation type, which is
  +//   pushed on a new line
  +//   (3) keyword and identifier on one line, then every binder and the
  +//   computation type on separate lines; binders can also be spread over
  +//   multiple lines
  +// In case (2), the first parameter controls indentation for the
  +// computation type. In case (3), first parameter is indentation for each
  +// of the binders, second parameter is indendation for the computation
  +// type.
  +type annotation_style =
  +  | Binders of int * int // val f (x1:t1) ... (xn:tn) : C
  +  | Arrows of int * int //  val f : x1:t1 -> ... -> xn:tn -> C
  +
  +// decide whether a type signature can be printed in the format
  +//   val f (x1:t1) ... (xn:tn) : C
  +// it can't if either not all args are annotated binders or if it has no
  +// arguments, in which case it will be printed using the colon + arrows style
  +let all_binders_annot e =
  +  let is_binder_annot b =
  +    match b.b with
  +    | Annotated _ -> true
  +    | _ -> false
  +  in
  +  let rec all_binders e l =
  +    match e.tm with
  +    | Product(bs, tgt) -> if List.for_all is_binder_annot bs then all_binders tgt (l+ List.length bs) else (false, 0)
  +    | _ -> (true, l+1)
  +  in
  +  let b, l = all_binders e 0 in
  +  if b && l > 1 then true else false
  +
  +
   (* ****************************************************************************)
   (*                                                                            *)
   (*                   Taking care of comments                                  *)
  
positive.code: and is_meta_qualifier aq =
    match aq with
    | Some (Meta _) -> true
    | _ -> false
  
  and is_binder_annot b = match b.b with
    | Annotated _ -> true
    | _ -> false
  
  (* is_atomic is true if the binder must be parsed atomically *)
  
negative.code:      has_fsdoc: bool;
       is_fsdoc: bool} //is a standalone fsdoc
  let dummy_meta = {r = dummyRange; has_qs = false; has_attrs = false; has_fsdoc = false; is_fsdoc = false}
  
  // TODO: rewrite in terms of with_comment_sep
  let with_comment printer tm tmrange origin =
  