Struct Embedding in F#
// F# supports composition of types through inheritance and interfaces.
// This example demonstrates a similar concept to Go's struct embedding.
open System
// Define a base record type
type Base = {
Num: int
}
// Define a function for the base type
let describe (b: Base) =
sprintf "base with num=%d" b.Num
// Define a container record type that includes Base
type Container = {
Base: Base
Str: string
}
// Define a discriminated union type for the interface
type Describer =
| BaseDescriber of Base
| ContainerDescriber of Container
let main() =
// Create a Container instance
let co = {
Base = { Num = 1 }
Str = "some name"
}
// Access the Base fields directly on Container
printfn "co={num: %d, str: %s}" co.Base.Num co.Str
// Alternatively, we can spell out the full path
printfn "also num: %d" co.Base.Num
// Call the describe function on the Base part of Container
printfn "describe: %s" (describe co.Base)
// Demonstrate polymorphism using the Describer type
let d = ContainerDescriber co
let describePolymorphic (describer: Describer) =
match describer with
| BaseDescriber b -> describe b
| ContainerDescriber c -> describe c.Base
printfn "describer: %s" (describePolymorphic d)
main()This F# code demonstrates concepts similar to struct embedding in Go. Here’s an explanation of the key points:
We define a
Baserecord type with aNumfield, similar to thebasestruct in Go.The
describefunction is defined separately, taking aBaseas an argument, rather than being a method on the type.We create a
Containerrecord type that includes aBasefield, mimicking the embedding in Go.The
Describerdiscriminated union type is used to demonstrate polymorphism, similar to thedescriberinterface in Go.In the
mainfunction, we create aContainerinstance and show how to access its fields.We demonstrate polymorphism using the
Describertype and pattern matching.
To run this F# program:
$ dotnet fsi struct-embedding.fsx
co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1This example shows how F# can achieve similar functionality to Go’s struct embedding through composition and discriminated unions. While the syntax and approach differ, the core concept of type composition is preserved.