我使用以下代码convert a tuple to a list,然后我试图找到列表的平均值。但我遇到了这个错误。
The type 'obj list option' is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method
以下是代码:
let Average (touple) =
let tupleToList t =
if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType())
then Some (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.toList)
else None
let k=tupleToList touple
let mutable sum=0
for i in k do
sum<-sum+k.[i]
let touple4= 6,18,6,9
Average touple4
答案 0 :(得分:3)
tupleToList
会返回option列表;也就是说,如果给定的参数是一个元组,它会返回Some
列表,否则为None
无法枚举选项类型(在其上使用for循环),因此您需要验证是否获得Some
并在其中提取列表(或者如果您有None
则执行其他操作)
一种方法是使用pattern matching
match tupleToList touple with
| Some k -> // use k to do what you want
| None -> // do something else
请注意表达式中的所有路径必须返回相同的类型;匹配中的所有分支必须返回相同类型的东西(例如:在无案例中返回0或者如果你有一些列表则返回一些总和而对于无则返回无)
你也可以在Option module
中使用一些功能作为旁注,您应该查看List module内部的内容,以简单地计算其值。
答案 1 :(得分:1)
您的tupleToList函数返回一个Option。要枚举结果,您必须使用模式匹配或修改函数以返回列表。在这种情况下,它非常简单 - 如果参数不是元组,则返回一个空列表。
元组可以包含不同的类型,因此返回的列表将是一个obj列表。您需要将它(或unbox和cast)转换为支持(+)和DivideByInt运算符的类型来计算平均值。转换是一个更好的解决方案,因为它可以使用不同类型的元组(例如,int * float)
您还应该尝试使用功能更多且命令性更少的编程风格。
let Average (tuple) =
let tupleToList t =
if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType())
then Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.toList
else []
tuple
|> tupleToList
|> List.map System.Convert.ToDouble
|> List.average
let tuple4= 6,18,6,9
Average tuple4