F# 可变变量';指数';在seq{}中以无效方式使用?
在下面的代码中,编译器在F# 可变变量';指数';在seq{}中以无效方式使用?,f#,F#,在下面的代码中,编译器在index iterateTupleMemberTypes(t.GetGenericArguments())columnNames index |>ignore上出错 |错误-> printfn“名称:%s类型:%A”(列名称。[索引])t 索引映射 让myFile=CsvProvider.GetSample() 设firstRow=myFile.Rows |>Seq.head 让tupleType=firstRow.GetType() 让tupleArguments=t
index iterateTupleMemberTypes(t.GetGenericArguments())columnNames index |>ignore上出错
|错误->
printfn“名称:%s类型:%A”(列名称。[索引])t
索引映射
让myFile=CsvProvider.GetSample()
设firstRow=myFile.Rows |>Seq.head
让tupleType=firstRow.GetType()
让tupleArguments=tupleType.GetGenericaArguments()
设m=iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
它后面的语句,让index=0
,隐藏了可变变量index
的定义。另外,要使可变表按顺序工作,需要引用 它后面的语句,let index=0
,隐藏了可变变量的定义index
。另外,要使可变表按顺序工作,需要引用 它后面的语句,let index=0
,隐藏了可变变量的定义index
。另外,要使可变表按顺序工作,需要引用 它后面的语句,let index=0
,隐藏了可变变量的定义index
。另外,要使可变表按顺序工作,需要引用 在@Ming Tang的建议下,我将可变变量改为ref
,现在可以工作了。然而,这是一种根本不使用可变/ref变量的方法吗
let rec iterateTupleMemberTypes (tupleArgTypes: System.Type[]) (columnNames: string[]) startingIndex =
seq {
let index = ref startingIndex
for t in tupleArgTypes do
match t.IsGenericType with
| true ->
yield! iterateTupleMemberTypes (t.GetGenericArguments()) columnNames !index
| false ->
printfn "Name: %s Type: %A" (columnNames.[!index]) t
yield (columnNames.[!index]), t
index := !index + 1
} |> dict
let myFile = CsvProvider<"""d:\temp\sample.txt""">.GetSample()
let firstRow = myFile.Rows |> Seq.head
let tupleType = firstRow.GetType()
let tupleArgTypes = tupleType.GetGenericArguments()
let m = iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
let rec iterateTupleMemberTypes(tupleArgTypes:System.Type[])(columnNames:string[])startingIndex=
序号{
let index=参考起始索引
对于tupleArgTypes中的t
将t.IsGenericType与
|正确->
yield!iterateTupleMemberTypes(t.GetGenericArguments())columnNames!索引
|错误->
printfn“名称:%s类型:%A”(列名称。[!索引])t
收益率(列名称。[!索引]),t
索引:=!索引+1
}|>dict
让myFile=CsvProvider.GetSample()
设firstRow=myFile.Rows |>Seq.head
让tupleType=firstRow.GetType()
让tupleArguments=tupleType.GetGenericaArguments()
设m=iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
根据@Ming Tang的建议,我将可变变量更改为ref
,现在可以工作了。然而,这是一种根本不使用可变/ref变量的方法吗
let rec iterateTupleMemberTypes (tupleArgTypes: System.Type[]) (columnNames: string[]) startingIndex =
seq {
let index = ref startingIndex
for t in tupleArgTypes do
match t.IsGenericType with
| true ->
yield! iterateTupleMemberTypes (t.GetGenericArguments()) columnNames !index
| false ->
printfn "Name: %s Type: %A" (columnNames.[!index]) t
yield (columnNames.[!index]), t
index := !index + 1
} |> dict
let myFile = CsvProvider<"""d:\temp\sample.txt""">.GetSample()
let firstRow = myFile.Rows |> Seq.head
let tupleType = firstRow.GetType()
let tupleArgTypes = tupleType.GetGenericArguments()
let m = iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
let rec iterateTupleMemberTypes(tupleArgTypes:System.Type[])(columnNames:string[])startingIndex=
序号{
let index=参考起始索引
对于tupleArgTypes中的t
将t.IsGenericType与
|正确->
yield!iterateTupleMemberTypes(t.GetGenericArguments())columnNames!索引
|错误->
printfn“名称:%s类型:%A”(列名称。[!索引])t
收益率(列名称。[!索引]),t
索引:=!索引+1
}|>dict
让myFile=CsvProvider.GetSample()
设firstRow=myFile.Rows |>Seq.head
让tupleType=firstRow.GetType()
让tupleArguments=tupleType.GetGenericaArguments()
设m=iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
根据@Ming Tang的建议,我将可变变量更改为ref
,现在可以工作了。然而,这是一种根本不使用可变/ref变量的方法吗
let rec iterateTupleMemberTypes (tupleArgTypes: System.Type[]) (columnNames: string[]) startingIndex =
seq {
let index = ref startingIndex
for t in tupleArgTypes do
match t.IsGenericType with
| true ->
yield! iterateTupleMemberTypes (t.GetGenericArguments()) columnNames !index
| false ->
printfn "Name: %s Type: %A" (columnNames.[!index]) t
yield (columnNames.[!index]), t
index := !index + 1
} |> dict
let myFile = CsvProvider<"""d:\temp\sample.txt""">.GetSample()
let firstRow = myFile.Rows |> Seq.head
let tupleType = firstRow.GetType()
let tupleArgTypes = tupleType.GetGenericArguments()
let m = iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
let rec iterateTupleMemberTypes(tupleArgTypes:System.Type[])(columnNames:string[])startingIndex=
序号{
let index=参考起始索引
对于tupleArgTypes中的t
将t.IsGenericType与
|正确->
yield!iterateTupleMemberTypes(t.GetGenericArguments())columnNames!索引
|错误->
printfn“名称:%s类型:%A”(列名称。[!索引])t
收益率(列名称。[!索引]),t
索引:=!索引+1
}|>dict
让myFile=CsvProvider.GetSample()
设firstRow=myFile.Rows |>Seq.head
让tupleType=firstRow.GetType()
让tupleArguments=tupleType.GetGenericaArguments()
设m=iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
根据@Ming Tang的建议,我将可变变量更改为ref
,现在可以工作了。然而,这是一种根本不使用可变/ref变量的方法吗
let rec iterateTupleMemberTypes (tupleArgTypes: System.Type[]) (columnNames: string[]) startingIndex =
seq {
let index = ref startingIndex
for t in tupleArgTypes do
match t.IsGenericType with
| true ->
yield! iterateTupleMemberTypes (t.GetGenericArguments()) columnNames !index
| false ->
printfn "Name: %s Type: %A" (columnNames.[!index]) t
yield (columnNames.[!index]), t
index := !index + 1
} |> dict
let myFile = CsvProvider<"""d:\temp\sample.txt""">.GetSample()
let firstRow = myFile.Rows |> Seq.head
let tupleType = firstRow.GetType()
let tupleArgTypes = tupleType.GetGenericArguments()
let m = iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
let rec iterateTupleMemberTypes(tupleArgTypes:System.Type[])(columnNames:string[])startingIndex=
序号{
let index=参考起始索引
对于tupleArgTypes中的t
将t.IsGenericType与
|正确->
yield!iterateTupleMemberTypes(t.GetGenericArguments())columnNames!索引
|错误->
printfn“名称:%s类型:%A”(列名称。[!索引])t
收益率(列名称。[!索引]),t
索引:=!索引+1
}|>dict
让myFile=CsvProvider.GetSample()
设firstRow=myFile.Rows |>Seq.head
让tupleType=firstRow.GetType()
让tupleArguments=tupleType.GetGenericaArguments()
设m=iterateTupleMemberTypes tupleArgTypes myFile.Headers.Value 0
这种方法的惯用版本可能如下所示:
#r @"..\packages\FSharp.Data.2.2.2\lib\net40\FSharp.Data.dll"
open FSharp.Data
open System
type SampleCsv = CsvProvider<"Sample.csv">
let sample = SampleCsv.GetSample()
let rec collectLeaves (typeTree : Type) =
seq {
match typeTree.IsGenericType with
| false -> yield typeTree.Name
| true -> yield! typeTree.GetGenericArguments() |> Seq.collect collectLeaves
}
let columnTypes = (sample.Rows |> Seq.head).GetType() |> collectLeaves
let columnDefinitions = columnTypes |> Seq.zip sample.Headers.Value |> Map.ofSeq
let getDefinitions (sample : SampleCsv) = (sample.Rows |> Seq.head).GetType() |> collectLeaves |> Seq.zip sample.Headers.Value |> Map.ofSeq
#r@.\packages\FSharp.Data.2.2\lib\net40\FSharp.Data.dll”
打开FSharp.Data
开放系统
类型SampleCsv=CsvProvider
让sample=SampleCsv.GetSample()
让rec收集树叶(typeTree:Type)=
序号{
将typeTree.IsGenericType与匹配
|false->yield typeTree.Name
|true->yield!typeTree.GetGenericArguments()|>Seq.collectLeaves
}
让columnTypes=(sample.Rows |>Seq.head).GetType()|>collectLeaves
让columnDefinitions=columnTypes |>Seq.zip sample.Headers.Value |>Map.ofSeq
让getDefinitions(sample:SampleCsv)=(sample.Rows |>Seq.head).GetType()|>collectLeaves |>Seq.zip sample.Headers.Value |>Map.ofSeq
就个人而言,我不会太在意Map
与Dictionary
的性能(而是拥有不变的Map
),除非有数百个列