我有一个包含两列文本和计数的 CSV 文件。目标是从此文件转换:
some text once,1
some text twice,2
some text thrice,3
对此:
some text once,1
some text twice,1
some text twice,1
some text thrice,1
some text thrice,1
some text thrice,1
重复每行计数次数并将计数分布在那么多行上。
在我看来,这似乎是 Seq.unfold 的一个很好的候选者,在我们读取文件时会生成额外的行。我有以下生成器功能:
let expandRows (text:string, number:int32) =
if number = 0
then None
else
let element = text // "element" will be in the generated sequence
let nextState = (element, number-1) // threaded state replacing looping
Some (element, nextState)
FSI 产生以下函数签名:
val expandRows : text:string * number:int32 -> (string * (string * int32)) option
在 FSI 中执行以下操作:
let expandedRows = Seq.unfold expandRows ("some text thrice", 3)
产生预期的:
val it : seq<string> = seq ["some text thrice"; "some text thrice"; "some text thrice"]
问题是:如何将其插入更大的 ETL 管道的上下文中?例如:
File.ReadLines(inFile)
|> Seq.map createTupleWithCount
|> Seq.unfold expandRows // type mismatch here
|> Seq.iter outFile.WriteLine
下面的错误出现在管道上下文中的 expandRows 上。
Type mismatch.
Expecting a 'seq<string * int32> -> ('a * seq<string * int32>) option'
but given a 'string * int32 -> (string * (string * int32)) option'
The type 'seq<string * int 32>' does not match the type 'string * int32'
我期待 expandRows 返回字符串的序列,就像在我的独立测试中一样。由于这既不是“期望”也不是“给定”,我很困惑。有人可以指出我正确的方向吗?
代码要点在这里: https ://gist.github.com/akucheck/e0ff316e516063e6db224ab116501498