namespace rprint module Rprint = let printer = new System.Threading.AsyncLocal unit>() let _ = printer.Value <- System.Console.Write let rprint format = // This is a new friend of mine. kprintf takes a format string and a continuation. // it returns a function that takes enough values to satisfy the format string. // in the end it produces a string that is passed to the continuation. Printf.kprintf (fun s -> printer.Value s) format let rprintn format = Printf.kprintf (fun s -> printer.Value (s + System.Environment.NewLine)) format // Takes a thunk. All output printed through rprint gets redirected to a stringBuilder // for all calls to rprint within the extent of withOutputToString let withOutputToString f = let sb = System.Text.StringBuilder() let original = printer.Value // Bind om till StringBuilder printer.Value <- fun s -> sb.Append s |> ignore try f () sb.ToString().TrimEnd() finally printer.Value <- original let withOutputToStringBuilder (builder: System.Text.StringBuilder) f = let original = printer.Value printer.Value <- (fun s -> builder.Append(s) |> ignore) try f () finally printer.Value <- original