F#叉管

时间:2009-07-18 08:21:49

标签: f#

我有以下(工作)代码:

let a = 
    File.ReadAllLines("C:\ColorTable.dat")
    |> Array.filter (fun i -> i.StartsWith(" "))
    |> Array.iter (fun i -> 
        Console.WriteLine(@"ColorList.Add({0}, ""{1}"");", extract_num i, extract_col i)
        f.WriteLine(@"ColorList.Add({0}, ""{1}"");", extract_num i, extract_col i)
        )

函数extract_num和extract_col将正则表达式应用于文件的行并提取其中的一部分。然后我将格式化的字符串打印到控制台到文件。

为此,我将格式化部分写两次。这样做有什么更干净的方法?我可以定义一个接受extract_num和extract_col的函数来返回格式化的字符串并调用它两次,当然,为了学习,最常用的功能方法是什么?

出于我的想法,我可以将格式化的字符串输出到控制台和带有某种管道分叉的文件吗?

由于

3 个答案:

答案 0 :(得分:3)

这是一些代码......

open System.IO
let ComposeTextWriters (tws:TextWriter[]) =
    { new TextWriter() with 
        override this.Encoding = System.Text.Encoding.Default 
        override this.Write(c:char) =
            tws |> Array.iter (fun tw -> tw.Write(c)) }

let data = [(1,1); (2,2); (3,3)]

[<EntryPoint>]
let Main(_) =
    use fileToWrite = new StreamWriter(File.OpenWrite("out.txt")) :> TextWriter
    let stdout = System.Console.Out 
    let compositeOut = ComposeTextWriters [|fileToWrite;stdout|]
    data |> List.iter (fun (x,y) ->
        compositeOut.WriteLine("{0}: '{1}'", x, y))
    0

我不知道这是否是一个很好的方法,但它似乎有效。 ComposeTextWriters将TextWriters数组作为输入,并返回一个新的TextWriter,将所有输出写入所有输出。这是你要找的那种东西吗?

答案 1 :(得分:1)

如果我理解这个问题,你要求的“叉管”可能看起来像

let fork f g x = (f x); (g x);

你可以像这样使用它:

let extract i = sprintf "ColorList.Add(%A \"%A\")" (extract_num i) (extract_col i)

File.ReadAllLines("C:\ColorTable.dat")
   |> Array.filter (fun s -> s.StartsWith(" "))
   |> Array.iter (extract >> fork Console.WriteLine f.WriteLine);

(基于dahlbyk答案的代码)

答案 2 :(得分:0)

我会将你的逻辑分解为将值提取并打印到自己的函数中。此外,您的a始终为unit - 我怀疑您可能确实想要保存您要在其他地方使用的值。我可能会重写你的代码:

let a = 
    let extract_values s = (extract_num s),(extract_col s)
    let print_values (num,col) =
        let msg = sprintf "ColorList.Add(%A \"%A\")" num col
        Console.WriteLine(msg)
        f.WriteLine(msg)
        num,col
    File.ReadAllLines("C:\ColorTable.dat")
    |> Array.filter (fun s -> s.StartsWith(" "))
    |> Array.map extract_values
    |> Array.map print_values

a将是num,col对的数组。

如果您实际上并不关心提取的值,则可以返回一个字符串并将其直接传递给print

let extract_values s =
    sprintf "ColorList.Add(%A \"%A\")" (extract_num s) (extract_col s)
let print_values (s : string) =
    Console.WriteLine(s)
    f.WriteLine(s)
File.ReadAllLines("C:\ColorTable.dat")
|> Array.filter (fun s -> s.StartsWith(" "))
|> Array.map extract_values
|> Array.iter print_values