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
Base
record type with aNum
field, similar to thebase
struct in Go.The
describe
function is defined separately, taking aBase
as an argument, rather than being a method on the type.We create a
Container
record type that includes aBase
field, mimicking the embedding in Go.The
Describer
discriminated union type is used to demonstrate polymorphism, similar to thedescriber
interface in Go.In the
main
function, we create aContainer
instance and show how to access its fields.We demonstrate polymorphism using the
Describer
type 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=1
This 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.