anchor.diff:       | [] -> empty
        | x::xs -> List.fold (flip bop) x xs
     let joinWith bop xs = joinWith' bop xs
  -  let joinSep sep xs = xs |> joinWith' ^ fun l r -> l <^> (sep <^> r)
  -  let hsep xs = joinWith' (<+>) xs
  -  let hcat xs = joinWith' (<^>) xs
  -  let vsep xs = joinWith' (<.>) xs
  -  let vcat xs = joinWith' (<..>) xs
  -  let fillSep xs = joinWith' (</>) xs
  +
  +  let joinSep sep xs = xs |> joinWith' ^ fun l r -> join3 l sep r
  +
  +  let hsep    xs = joinWith' (<+>)  xs
  +  let hcat    xs = joinWith' (<^>)  xs
  +  let vsep    xs = joinWith' (<.>)  xs
  +  let vcat    xs = joinWith' (<..>) xs
  +  let fillSep xs = joinWith' (</>)  xs
     let fillCat xs = joinWith' (<//>) xs
   
     let sep xs = group ^ vsep xs
     let cat xs = group ^ vcat xs
   
  -  let inline enclose' (l: Doc, r: Doc) d = l <^> (d <^> r)
  +  let inline enclose' (l, r) d = join3 l d r
     let enclose (l, r) d = enclose' (l, r) d
  -  let squotes d = enclose' lrsquote d
  -  let dquotes d = enclose' lrdquote d
  -  let parens d = enclose' lrparen d
  -  let angles d = enclose' lrangle d
  -  let braces d = enclose' lrbrace d
  +
  +  let squotes  d = enclose' lrsquote  d
  +  let dquotes  d = enclose' lrdquote  d
  +  let parens   d = enclose' lrparen   d
  +  let angles   d = enclose' lrangle   d
  +  let braces   d = enclose' lrbrace   d
     let brackets d = enclose' lrbracket d
   
     type t =
  -   | NIL
  -   | PRINT of text: string * Lazy<t>
  -   | LINEFEED of prefix: string * Lazy<t>
  -   | OBJ of obj: obj * Lazy<t>
  +   | Nil
  +   | Print of text: string * Lazy<t>
  +   | Linefeed of prefix: string * Lazy<t>
  +   | Obj of obj: obj * Lazy<t>
   
     type [<AbstractClass>] Actions () =
       abstract Line: unit -> unit
  
positive.code:   let inline outputWithFun write maxCols doc =
      outputWithActions
        {new Actions () with
          member this.Write s = write s}
        maxCols
        doc
  
  
negative.code: 
    let rec output (actions: Actions) doc =
      match force doc with
       | Nil -> ()
       | Print (str, doc) ->
         actions.Write str
         output actions doc
       | Obj (obj, doc) ->
         actions.User obj
         output actions doc
       | Linefeed (prefix, doc) ->
         actions.Line ()
         actions.Write prefix
         output actions doc
  
    let rec fits maxCols usedCols doc =
      usedCols <= maxCols &&
      match force doc with
       | Nil | Linefeed _ -> true
       | Obj (_, doc) ->
         fits maxCols usedCols doc
       | Print (str, doc) ->
         fits maxCols (usedCols + str.Length) doc
  
    type Docs =
      | Done
      | Docs of string * Doc * Docs
  
    let rec layout maxColsOr0 usedCols = function
      | Done -> Nil
      | Docs (prefix, doc, rest) ->
        match doc with
         | Lazy doc ->
           layout maxColsOr0 usedCols ^ Docs (prefix, force doc, rest)
         | Empty ->
           layout maxColsOr0 usedCols rest
         | Join (lhs, rhs) ->
           layout maxColsOr0 usedCols ^
           Docs (prefix, lhs, Docs (prefix, rhs, rest))
         | Nest (txt, doc) ->
           layout maxColsOr0 usedCols ^ Docs (prefix + txt, doc, rest)
         | Text str ->
           Print (str, lazy layout maxColsOr0 (usedCols + str.Length) rest)
         | User obj ->
           Obj (obj, lazy layout maxColsOr0 usedCols rest)
         | Line _ ->
           Linefeed (prefix, lazy layout maxColsOr0 prefix.Length rest)
         | Choice (wide, narrow) ->
           let wide = layout maxColsOr0 usedCols ^ Docs (prefix, wide, rest)
           if maxColsOr0 = 0 || fits maxColsOr0 usedCols ^ lazy wide
           then wide
           else layout maxColsOr0 usedCols ^ Docs (prefix, narrow, rest)
         | With f ->
           layout maxColsOr0 usedCols ^ Docs (prefix, f usedCols prefix, rest)
  
    let outputWithActions actions maxCols doc =
      let maxColsOr0 =
  