2009-07-18 13 views
2

I持って次のコード(作業)ビット: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は、ファイルの行に正規表現を適用し、その一部を抽出します。次に、書式設定された文字列をファイルに出力します。

これを行うには、フォーマットされた部分を2回書きます。これを行うもっとクリーンな方法は何ですか?私は、フォーマットされた文字列を返すextract_numとextract_colを受け入れる関数を定義することができますが、これを2回呼び出すことはできますが、学習のために最も多くのものは機能のやり方ですか?

私は、フォーマットされた文字列をコンソールとファイルの両方に出力することはできますか?

おかげ

答えて

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は、TextWriterの配列を入力として受け取り、すべての出力をすべてのTextWriterに書き込む新しいTextWriterを返します。これはあなたが探しているものですか?

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 

anum,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 
1

私は質問を理解していた場合は、「フォークパイプ」あなたは

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); 
:「

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

のようになります。そして、あなたはこのようにそれを使用することができますを求めて再10

(dahlbykの回答コードに基づく)