type MpCalc<'a> = { add: 'a -> 'a -> 'a; min: 'a -> 'a -> 'a; } type Mp<'a> = struct val value: 'a val calc: MpCalc<'a> new(v, c) = { value = v; calc = c } static member (+) (x: Mp<'a>, y: Mp<'a>) = new Mp<_>(x.calc.min x.value y.value, x.calc) static member (*) (x: Mp<'a>, y: Mp<'a>) = new Mp<_>(x.calc.add x.value y.value, x.calc) end let inline toMp v = new Mp<_>(v, { add = (+); min = Operators.min; }) [] let main argv = printfn "1 + 1 = %A" ((toMp 1) + (toMp 1)).value printfn "2 + 3 = %A" ((toMp 2) + (toMp 3)).value printfn "2 * 3 = %A" ((toMp 2) * (toMp 3)).value printfn "2 * 0 = %A" ((toMp 2) * (toMp 0)).value printfn "3.0 + infinity = %A" ((toMp 3.0) + (toMp Operators.infinity)).value printfn "3.0 * infinity = %A" ((toMp 3.0) * (toMp Operators.infinity)).value 0