【发布时间】:2016-12-14 13:24:04
【问题描述】:
我有以下函数可以将 csv 文件转换为特定的 txt 模式(CNTKTextFormat Reader 预期):
open System.IO
open FSharp.Data;
open Deedle;
let convert (inFileName : string) =
let data = Frame.ReadCsv(inFileName)
let outFileName = inFileName.Substring(0, (inFileName.Length - 4)) + ".txt"
use outFile = new StreamWriter(outFileName, false)
data.Rows.Observations
|> Seq.map(fun kvp ->
let row = kvp.Value |> Series.observations |> Seq.map(fun (k,v) -> v) |> Seq.toList
match row with
| label::data ->
let body = data |> List.map string |> String.concat " "
outFile.WriteLine(sprintf "|labels %A |features %s" label body)
printf "%A" label
| _ ->
failwith "Bad data."
)
|> ignore
奇怪的是,在 F# 交互式面板中运行后,输出文件为空,printf 根本不打印。
如果我删除 ignore 以确保正在处理实际行(通过返回空值序列来证明),而不是得到一个空文件:
val it : seq<unit> = Error: Cannot write to a closed TextWriter.
之前,我使用 let 声明 StreamWriter 并手动处理它,但我也生成了空文件或仅生成几行(比如千分之五)。
这里发生了什么?另外,如何解决文件写入问题?
【问题讨论】:
-
Seq.map很懒惰。你想要的是Seq.iter,它接受一个副作用函数(一个返回unit),并且,非懒惰地,将它应用于序列中的每个项目。