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.