F# 写入文件更改返回类型的行为

标签 f# cntk

我有以下函数将 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.
之前,我使用 StreamWriter 声明 let 并手动处理它,但我也生成了空文件或仅几行(比如千分之五)。

这里发生了什么?另外,如何修复文件写入?

最佳答案

Seq.map 返回一个惰性序列,在迭代之前不会对其进行评估。您当前没有在 convert 中对其进行迭代,因此不会处理任何行。如果您返回 Seq<unit> 并在 convert 之外对其进行迭代,则 outFile 将已经关闭,这就是您看到异常的原因。

您应该使用 Seq.iter 代替:

data.Rows.Observations
    |> Seq.iter (fun kvp -> ...)

关于F# 写入文件更改返回类型的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41143789/

相关文章:

c# - 单元素元组和零元素元组有什么用?

python - azure 机器学习工作台 - 准确性高,但置信度分数非常低

c++ - CNTK C++ API 中 Function::Forward 和 Trainer::TrainMinibatch 的区别

f# - fscheck 生成大小在 min 和 max 之间的字符串

c# - 这是计算表达式的候选者吗?

macos - 为什么我没有使用此 F# 代码在 OSX 上获得输出,但我在 Windows 上获得了输出

cntk - 微软CNTK自动微分

python - CNTK运行时错误

python - CNTK:从用于多 GPU 训练的 numpy 数组创建 MinibatchSource

sql-server - 无法使用 F# TypeProvider 读取日期