Reputation: 121
I have two types and their corresponding values.
I'm attempting to come up with a generic function that adds values of either type.
That is, a function that gets two values of the same type and adds them. For example, MyInt 7
and MyInt 13
should output MyInt 20
.
The function won't work. What am I doing wrong here?
type MyInt = MyInt of int
let xInt = MyInt 7
let yInt = MyInt 13
type MyDec = MyDec of decimal
let xDec = MyDec 7.0M
let yDec = MyDec 13.0M
let add<'a> (x:'a) (y:'a) : 'a =
let ('a innerX) = x // unwrap the inner value
let ('a innerY) = y // unwrap the inner value
'a (innerX + innerY) // add the inner values and then wrap the result
Upvotes: 0
Views: 44
Reputation: 17123
There are a couple of issues here. The first is that the MyInt
constructor is different from the MyInt
type, even though they look identical. Let's clarify that by using MakeMyInt
as the constructor name instead:
type MyInt = MakeMyInt of int
type MyDec = MakeMyDec of decimal
You cannot construct or destruct a union value using a type name (e.g. MyInt
) or type parameter, ('a
). You have to use a constructor (e.g. MakeMyInt
).
Now, if you want to be able to add instances of your types, the best approach is to create a static addition member for each:
type MyInt =
MakeMyInt of int
static member (+)(MakeMyInt x, MakeMyInt y) =
MakeMyInt (x + y)
type MyDec =
MakeMyDec of decimal
static member (+)(MakeMyDec x, MakeMyDec y) =
MakeMyDec (x + y)
With those in place you can add instances of both types directly:
printfn $"{xInt + yInt}" // MakeMyInt 20
printfn $"{xDec + yDec}" // MakeMyDec 20.0M
No generic addition function is needed.
Upvotes: 3