Struct Embedding in Standard ML

Standard ML supports record types, which can be used to create struct-like structures. However, it doesn’t have a direct equivalent to Go’s struct embedding. We’ll simulate this behavior using nested records and functions.

(* Define a base record type *)
type base = {num: int}

(* Function to describe the base *)
fun describe_base (b: base) : string =
    "base with num=" ^ Int.toString (#num b)

(* Define a container record type *)
type container = {base: base, str: string}

(* Main function *)
fun main () =
    let
        (* Create a container instance *)
        val co = {base = {num = 1}, str = "some name"}

        (* Access fields *)
        val _ = print ("co={num: " ^ Int.toString (#num (#base co)) ^ 
                       ", str: " ^ (#str co) ^ "}\n")

        (* Access using full path *)
        val _ = print ("also num: " ^ Int.toString (#num (#base co)) ^ "\n")

        (* Call the describe function *)
        val _ = print ("describe: " ^ describe_base (#base co) ^ "\n")

        (* Define a describer function type *)
        type describer = base -> string

        (* Use the describe_base function as a describer *)
        val d : describer = describe_base

        (* Call the describer function *)
        val _ = print ("describer: " ^ d (#base co) ^ "\n")
    in
        ()
    end

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

In this Standard ML version:

  1. We define a base record type with a num field.

  2. We create a describe_base function that takes a base record and returns a string description.

  3. We define a container record type that includes a base record and a str field.

  4. In the main function, we create a container instance and demonstrate how to access its fields.

  5. We show how to call the describe_base function on the base part of the container.

  6. We define a describer function type and use describe_base as an implementation of this type.

To run this program, save it to a file (e.g., struct_embedding.sml) and use an Standard ML interpreter or compiler. For example, with the Moscow ML interpreter:

$ mosml struct_embedding.sml
co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1

This example demonstrates how to simulate struct-like behavior in Standard ML using records and functions. While Standard ML doesn’t have direct struct embedding like Go, we can achieve similar functionality through nested records and carefully designed functions.