2013-05-31 40 views
1

這些是函數定義。如何使用管線運算符重寫此函數

func1: 'a -> unit 
func2: 'b -> 'a 
func3: string -> 'b list  

目前功能

let f = Seq.iter((fun a -> func1(func2 a)) func3(s) 

這是據我得到

let f = func3(s) 
      |> ((fun a -> func2 a 
         |> func1) 
      |> Seq.iter) 

我有一種感覺,應該可以鬆拉姆達與括號。

回答

6

你可以不使用管道,簡單地

Seq.iter (func1 << func2) << func3 

(這是與一些參數[比func3相同]和相同的功能輸出比Seq.iter)。

您可以測試它

let func1 x = printfn "Number: %d" x 

let func2 (a, b) = a + b 

let func3 = Seq.map (fun n -> (n, 2 * n)) 

let f : (seq<_> -> unit) = Seq.iter (func1 << func2) << func3 

f [1..5] 

與輸出

Number: 3 
Number: 6 
Number: 9 
Number: 12 
Number: 15 

val func1 : x:int -> unit 
val func2 : a:int * b:int -> int 
val func3 : (seq<int> -> seq<int * int>) 
val f : (seq<int> -> unit) 
val it : unit =() 

:)

4

可以使用函數組合操作者>>

func3() |> Seq.iter (func2 >> func1)

2

我認爲問題是,你爲什麼要使用管道運算符?

我覺得你的原代碼很可讀。爲了使用它們,您不應該嘗試使用管線運算符(或函數組合)。現在,在您的代碼中,輸入s出現在結尾處,這有點不幸(您無法完全瞭解代碼的主要輸入內容)。我可能會重寫爲(也s是不是一個真正的描述性名稱):

s |> func3 
    |> Seq.iter (fun a -> func1 (func2 a)) 

您可以使用函數組合太 - 而是因爲它不(總是)我不經常用它,以幫助可讀性。但在參數Seq.iter中使用它可能是相當合理的。

在一個完全無關的音符,你可以只使用for循環寫:

for a in func3 s do 
    func1 (func2 a) 

其實我覺得這比其他任何版本的代碼在這裏更易讀(如果F#爲您提供了迭代語言功能這些序列完全符合你的需求,爲什麼不使用它?)