在 F# 数组函数中使用有区别的联合时如何定义零元素
How to define a zero element when using discriminated unions in F# Array functions
好的,一个问题,我想在数组函数中使用一个可区分的联合数组。在下面的代码中,我定义了一个 ResultVari
类型,它可以是 Unknown
或浮点值。我还为该类型定义了中缀加运算符,只有当两个参数都不是 Unknown
时,它 returns 才是一个值。这很好用。
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
使用 summation2
程序按预期工作,example1
的总和为 12.6,example2
的总和为 Unknown
。
但我不明白为什么 summation
不起作用 - 编译器抱怨 "this value is not a function and cannot be applied"。在另一次尝试(未显示)中,我还得到了一个丢失的 get_Zero 元素的错误,据我所知 - sum 函数必须使用某种类型的零定义来开始求和,并使用 fold 函数我的 Value(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)
那么代码就变成了:
let summation (varArray:ResultVari array) =
Array.sum varArray
这是有道理的,因为当您求和时需要从零开始并且没有零成员,编译器不知道从哪里开始。
好的,一个问题,我想在数组函数中使用一个可区分的联合数组。在下面的代码中,我定义了一个 ResultVari
类型,它可以是 Unknown
或浮点值。我还为该类型定义了中缀加运算符,只有当两个参数都不是 Unknown
时,它 returns 才是一个值。这很好用。
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
使用 summation2
程序按预期工作,example1
的总和为 12.6,example2
的总和为 Unknown
。
但我不明白为什么 summation
不起作用 - 编译器抱怨 "this value is not a function and cannot be applied"。在另一次尝试(未显示)中,我还得到了一个丢失的 get_Zero 元素的错误,据我所知 - sum 函数必须使用某种类型的零定义来开始求和,并使用 fold 函数我的 Value(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)
那么代码就变成了:
let summation (varArray:ResultVari array) =
Array.sum varArray
这是有道理的,因为当您求和时需要从零开始并且没有零成员,编译器不知道从哪里开始。