I was reading Don Syme’s really well written comments on static abstract members on interfaces, and I saw his comments on there now being three ways to do type level abstractions.
I then realised his example for explicit function passing, i.e. this one:
let f0 add x y =
(add x y, add y x)
is a very concise form of what I’ve been doing with records of functions as a means of function overloading. What I realised I don’t understand is, why the compiler is allowing me to do this in the first place
Take this example:
// won't work for int once type of x,y i.e. 'T is resolved to string
let adder x y = x + y
let strViaAdder = adder "str val1" "str val2"
strViaAdder.Dump("string via adder")
//let intViaAdder = adder 1 2
//intViaAdder.Dump ("int via adder")
Ignore the calls to Dump()
, that’s a utility function that LinqPad provides.
Once the compiler infers the type of x
and y
it won’t let me call it with values of other types, but in the f0
function above, it will leave the parameters of the fAdd
function as generic, so this’ll work:
let doAdd fAdd x y =
fAdd x y
type MyStr = {StrVal : string}
type MyInt = {IntVal : int}
let myStr = {StrVal = "some val"}
let myStr1 = {StrVal = "another val"}
let myInt = {IntVal = 1}
let myInt1 = {IntVal = 2}
let addMyStr {StrVal = xVal} {StrVal = yVal} = xVal + yVal
let addMyInt {IntVal = x} {IntVal = y} = x + y
let myStrAdded = doAdd addMyStr myStr myStr1
let myIntAdded = doAdd addMyInt myInt myInt1
myStrAdded.Dump ("added strings")
myIntAdded.Dump ("added integers")
No need to inline
f0
, and its parameters remain generic. I realised I didn’t notice this when using records of functions, I was just happily using them, but Don’s example made me see the gap in my understanding.
Can someone explain to my what’s going on here ?