OK, a question, I would like to use an array of discriminated unions in the Array functions. In the code below, I define a type ResultVari
that is either Unknown
or a floating point value. I also define the infix plus operator for the type, which returns a value only if both args are not Unknown
. This works fine.
type ResultVari =
| Unknown
| Value of float
static member (+) (a,b) = // add two ResultVari's together
match a,b with
| Value(av),Value(bv) -> Value(av + bv) // only has a value if both args do.
| _ -> Unknown
(* Summation of array of ResultVari, such that if any are unknown then the result is Unknown *)
let example1 = [| Value(4.0); Value(5.5); Value(3.1) |] // summation should be 12.6
let example2 = [| Value(4.0); Unknown; Value(3.1) |] // summation should be Unknown
let summation (varArray:ResultVari array) =
Array.sum (+) varArray //ERROR this value is not a function and cannot be applied
let summation2 (varArray:ResultVari array) =
Array.fold (+) (Value(0.0)) varArray // Works
let sum_example1 = summation2 example1
let sum_example2 = summation2 example2
printfn "%A" sum_example1 // 12.6
printfn "%A" sum_example2 // Unknown
Using summation2
the program works as expected with the sum for example1
being 12.6 and for example2
being Unknown
.
But I don't understand why summation
doesn't work - the compiler complains "this value is not a function and cannot be applied". In another attempt (not shown), I also got the error of a missing get_Zero element which I understand -- the sum function has to use some type of a zero definition to start the summation, and using the fold function with my Value(0.0) as the start value like in summation2
solves that.
So is there a way to define a get_Zero element for a discriminated union, or would I have to use a record type instead for ResultVari? Then I could use Array.sum instead of using Array.fold.
You need to add a zero
element to use array.sum - like this:
type ResultVari =
| Unknown
| Value of float
static member (+) (a,b) = // add two ResultVari's together
match a,b with
| Value(av),Value(bv) -> Value(av + bv) // only has a value if both args do.
| _ -> Unknown
static member Zero with get() = Value(0.0)
Then the code becomes:
let summation (varArray:ResultVari array) =
Array.sum varArray
This makes sense because when you sum something you need to start from zero and without the zero member, the compiler doesn't know where to start.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.