String Formatting in Standard ML

(* Standard ML doesn't have a built-in struct type, so we'll use a record type instead *)
type point = {x: int, y: int}

(* Standard ML doesn't have a printf function, so we'll define our own *)
fun printf format args =
    let
        fun replace_percent_s s [] = s
          | replace_percent_s s (arg::args) =
            let
                val (before, after) = Substring.position "%s" (Substring.full s)
            in
                replace_percent_s 
                    ((Substring.string before) ^ arg ^ 
                     (Substring.string (Substring.triml 2 after)))
                    args
            end
    in
        print (replace_percent_s format (map (fn x => x) args))
    end

(* Main function *)
fun main () =
    let
        val p = {x=1, y=2}
    in
        (* Printing a record *)
        printf "struct1: %s\n" ["{x=" ^ Int.toString (#x p) ^ ", y=" ^ Int.toString (#y p) ^ "}"];
        
        (* Standard ML doesn't have a built-in way to print the type, so we'll skip this *)
        printf "type: point\n" [];
        
        (* Printing a boolean *)
        printf "bool: %s\n" [Bool.toString true];
        
        (* Printing integers *)
        printf "int: %s\n" [Int.toString 123];
        printf "bin: %s\n" [StringCvt.padLeft #"0" 8 (Int.fmt StringCvt.BIN 14)];
        
        (* Printing a character *)
        printf "char: %s\n" [Char.toString (Char.chr 33)];
        
        (* Printing in hexadecimal *)
        printf "hex: %s\n" [StringCvt.padLeft #"0" 2 (Int.fmt StringCvt.HEX 456)];
        
        (* Printing floats *)
        printf "float1: %s\n" [Real.toString 78.9];
        printf "float2: %s\n" [Real.fmt (StringCvt.SCI (SOME 6)) 123400000.0];
        
        (* Printing strings *)
        printf "str1: %s\n" ["\"string\""];
        printf "str2: %s\n" ["\"\\\"string\\\"\""];
        
        (* Printing a string in hexadecimal *)
        printf "str3: %s\n" [String.translate (fn c => StringCvt.padLeft #"0" 2 (Int.fmt StringCvt.HEX (Char.ord c))) "hex this"];
        
        (* Standard ML doesn't have pointers, so we'll skip this *)
        
        (* Formatting with width *)
        printf "width1: |%s|%s|\n" [StringCvt.padLeft #" " 6 (Int.toString 12), 
                                    StringCvt.padLeft #" " 6 (Int.toString 345)];
        
        (* Formatting floats with width and precision *)
        printf "width2: |%s|%s|\n" [StringCvt.padLeft #" " 6 (Real.fmt (StringCvt.FIX (SOME 2)) 1.2),
                                    StringCvt.padLeft #" " 6 (Real.fmt (StringCvt.FIX (SOME 2)) 3.45)];
        
        (* Left-justifying *)
        printf "width3: |%s|%s|\n" [StringCvt.padRight #" " 6 (Real.fmt (StringCvt.FIX (SOME 2)) 1.2),
                                    StringCvt.padRight #" " 6 (Real.fmt (StringCvt.FIX (SOME 2)) 3.45)];
        
        (* Formatting strings with width *)
        printf "width4: |%s|%s|\n" [StringCvt.padLeft #" " 6 "foo", 
                                    StringCvt.padLeft #" " 6 "b"];
        
        (* Left-justifying strings *)
        printf "width5: |%s|%s|\n" [StringCvt.padRight #" " 6 "foo", 
                                    StringCvt.padRight #" " 6 "b"];
        
        (* Standard ML doesn't have a separate sprintf function, 
           but we can use our printf function to print to standard output *)
        printf "sprintf: a %s\n" ["string"];
        
        (* Standard ML doesn't have a separate stderr stream, 
           so we'll just print to standard output *)
        printf "io: an %s\n" ["error"]
    end

(* Run the main function *)
val _ = main()

This Standard ML code demonstrates various string formatting techniques. Note that Standard ML doesn’t have a built-in printf function like Go, so we’ve implemented a basic version. Also, some concepts don’t have direct equivalents in Standard ML, so we’ve adapted or omitted them as appropriate.

To run this program, save it to a file (e.g., string_formatting.sml) and use your Standard ML interpreter. For example, if you’re using MLton:

$ mlton string_formatting.sml
$ ./string_formatting

Or if you’re using SML/NJ:

$ sml string_formatting.sml

The output will be similar to the original Go program, with some differences due to language limitations or differences in implementation.