类型' obj列表选项'不是可以使用此语法枚举其值的类型

时间:2015-09-22 19:57:16

标签: f# f#-interactive

我使用以下代码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

2 个答案:

答案 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