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
),除非有数百个列