use*_*742 3 arrays f# discriminated-union
好的,一个问题,我想在Array函数中使用一组有区别的联合.在下面的代码,我定义类型ResultVari要么是Unknown或浮点值.我还为类型定义了中缀加运算符,仅当两个args都没有时才返回值Unknown.这很好用.
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
Run Code Online (Sandbox Code Playgroud)
使用summation2该程序的工作原理与总和预计example1是12.6和example2为Unknown.
但我不明白为什么summation不起作用 - 编译器抱怨"这个值不是一个函数,不能应用".在另一次尝试(未显示)中,我也得到了一个缺失的get_Zero元素的错误,我理解 - sum函数必须使用某种类型的零定义来开始求和,并使用fold函数和我的值(0.0) )作为summation2解决那个问题的起始值.
那么有没有办法为有区别的联合定义get_Zero元素,或者我必须使用记录类型代替ResultVari?然后我可以使用Array.sum而不是使用Array.fold.
你需要添加一个zero元素来使用array.sum - 像这样:
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)
Run Code Online (Sandbox Code Playgroud)
然后代码变成:
let summation (varArray:ResultVari array) =
Array.sum varArray
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为当你总结一些你需要从零开始而没有零成员时,编译器不知道从哪里开始.