String Formatting in F#
open System
type Point = { X: int; Y: int }
let main() =
// F# offers several printing options for formatting values.
// For example, this prints an instance of our Point record.
let p = { X = 1; Y = 2 }
printfn "struct1: %A" p
// The %A format specifier provides a default representation,
// which includes field names for records.
printfn "struct2: %A" p
// To print the type of a value, use %O with GetType()
printfn "type: %O" (p.GetType())
// Formatting booleans is straightforward.
printfn "bool: %b" true
// There are many options for formatting integers.
// Use %d for standard, base-10 formatting.
printfn "int: %d" 123
// This prints a binary representation.
printfn "bin: %s" (Convert.ToString(14, 2))
// This prints the character corresponding to the given integer.
printfn "char: %c" (char 33)
// %x provides hex encoding.
printfn "hex: %x" 456
// There are also several formatting options for floats.
// For basic decimal formatting use %f.
printfn "float1: %f" 78.9
// %e and %E format the float in (slightly different versions of) scientific notation.
printfn "float2: %e" 123400000.0
printfn "float3: %E" 123400000.0
// For basic string printing use %s.
printfn "str1: %s" "\"string\""
// To double-quote strings, use %O.
printfn "str2: %O" "\"string\""
// To print a representation of a pointer, use %O with the address-of operator.
printfn "pointer: %O" (&&p)
// When formatting numbers you will often want to control the width and precision
// of the resulting figure. To specify the width of an integer, use a number after
// the % in the format specifier. By default, the result will be right-justified
// and padded with spaces.
printfn "width1: |%6d|%6d|" 12 345
// You can also specify the width of printed floats, though usually you'll also
// want to restrict the decimal precision at the same time with the width.precision syntax.
printfn "width2: |%6.2f|%6.2f|" 1.2 3.45
// To left-justify, use the - flag.
printfn "width3: |%-6.2f|%-6.2f|" 1.2 3.45
// You may also want to control width when formatting strings,
// especially to ensure that they align in table-like output.
// For basic right-justified width:
printfn "width4: |%6s|%6s|" "foo" "b"
// To left-justify use the - flag as with numbers.
printfn "width5: |%-6s|%-6s|" "foo" "b"
// So far we've seen printfn, which prints the formatted string to stdout.
// sprintf formats and returns a string without printing it anywhere.
let s = sprintf "sprintf: a %s" "string"
printfn "%s" s
// You can format+print to TextWriters other than stdout using fprintf.
fprintf stderr "io: an %s\n" "error"
main()
This F# code demonstrates various string formatting techniques, mirroring the functionality of the original Go example. Here are some key differences and notes:
F# uses
printfn
for formatted printing, which is similar to Go’sfmt.Printf
.The
%A
format specifier in F# is used for generic pretty-printing, which includes field names for records (similar to Go’s%+v
).F# doesn’t have a direct equivalent to Go’s
%#v
for syntax representation, so we omit this part.To get the type of a value in F#, we use
GetType()
method with%O
format specifier.For binary representation, we use
Convert.ToString(value, 2)
as F# doesn’t have a built-in binary format specifier.F# uses
&&
operator to get the address of a value, which is similar to Go’s&
.The width and precision formatting works similarly in F# as in Go.
F# uses
sprintf
for formatting to a string, which is equivalent to Go’sfmt.Sprintf
.For writing to stderr, F# uses
fprintf stderr
, which is similar to Go’sfmt.Fprintf(os.Stderr, ...)
.
This example showcases F#’s string formatting capabilities, which are quite similar to Go’s, allowing for easy transition between the two languages for this particular feature.