F # Write to the behavior change file by return type

I have the following function that converts csv files to a specific txt scheme (CNTKTextFormat Reader expected):

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

Oddly enough, the output file is empty after launching in the F # interactive panel and that printfdoesn't print at all.

If I delete ignoreto make sure that the actual lines are being processed (which is confirmed by returning seq from zeros), instead of an empty file I get:

val it : seq<unit> = Error: Cannot write to a closed TextWriter.

Before that, I declared StreamWriterwith help letand deleted it manually, but I also generated empty files or a few lines (say, 5 thousand).

What's going on here? Also, how to fix a file entry?

+4
source share
3 answers

Seq.map , , . convert, . Seq<unit> convert, outFile , .

Seq.iter:

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

, StreamWriter .Net, File.WriteAllLines. , :

let convert (inFileName : string) = 
    let lines = 
        Frame.ReadCsv(inFileName).Rows.Observations
        |> Seq.map(fun kvp ->
            let row = kvp.Value |> Series.observations |> Seq.map snd |> Seq.toList
            match row with
            | label::data ->
                let body = data |> List.map string |> String.concat " "
                printf "%A" label
                sprintf "|labels %A |features %s" label body
            | _ ->
                failwith "Bad data."
        )
    let outFileName = inFileName.Substring(0, (inFileName.Length - 4)) + ".txt"
    File.WriteAllLines(outFileName, lines)

: , Deedle. , , : 1, .

let lines = 
    File.ReadLines inFileName
    |> Seq.map (fun line -> 
        match Seq.toList(line.Split ',') with
        | label::data ->
            let body = data |> List.map string |> String.concat " "
            printf "%A" label
            sprintf "|labels %A |features %s" label body
        | _ ->
            failwith "Bad data."
    )
+3

, Seq.map . "Can not write to closed TextWriter": use IDisposable, . , . Seq.map , , StreamWriter use, , ( , Seq F #), StreamWriter .

Seq.map Seq.iter, .

+2

Source: https://habr.com/ru/post/1663751/


All Articles