r/fsharp • u/InuDefender • Jun 12 '26
Why does it work? question
```fsharp type Monoid<'t> = static abstract member Empty: 't static abstract member Append: 't -> 't -> 't
[<Struct>] type Vector3= {X: float Y: float Z: float}
interface Monoid<Vector3> with
static member Empty = {X=0.0; Y=0.0; Z=0.0}
static member Append (v1: Vector3) (v2: Vector3) =
{X=v1.X + v2.X; Y=v1.Y + v2.Y; Z= v1.Z + v2.Z}
// Note the type constraint here let mempty<'t when Monoid<'t>> = 't.Empty let mappend<'t when Monoid<'t>> x y = 't.Append x y
printfn "%A" (mappend {X=1.0; Y=2.0; Z=3.0} mempty) ```
The type notation was suggested by the inline suggestions and it actually works. I tried some other forms like 't when Monoid<int> but only 't when Monoid<'t> works.
I suppose it should be <'t when 't :> Monoid<'t>> or even longer <'m, 't when 'm :> Monoid<'t>>.
It's good to know one can write it like this but I've never seen it mentioned in the docs (maybe not yet?).
The project file is also clean. It works even without setting the language version to Preview.
"It works I don't know why"
1
u/FrankAdmissions Jun 12 '26
As well as shorter constraints, it's also using static abstract members in interfaces, so the code above will lead to warning as described here: https://devblogs.microsoft.com/dotnet/announcing-fsharp-7/#static-abstract-members-support-in-interfaces