2011-03-12 54 views
0

我此刻讀的書「真實世界的函數編程」,並想知道怎樣才能寫出這樣的:F# - 嵌套管道

let numbers = [ 1 .. 10 ] 
let isOdd(n) = (n%2 = 1) 
let square(n) = n * n 

let myList = 
    numbers 
    |> List.map square 
     |> List.iter(printfn "%d") 
    |> List.filter isOdd 
     |> List.iter(printfn "%d") 

第一次後,我已經發布的代碼將失敗List.iter()與消息說:

類型不匹配。期待一個單元 - > 「一但給予」 B列表 - >‘B 列表中的類型‘單元’不 匹配類型‘’名單’

我怎麼可以這樣做以上(在哪裏工作)?

+0

let isOdd(n)是布爾值,你的其他聲明是整數。爲什麼它應該喜歡它? – CarneyCode 2011-03-12 11:09:25

+0

@Carnotaurus - 我想先將List中的所有整數映射到方法'square' - 然後再次使用數字列表並獲得所有奇數。 – ebb 2011-03-12 11:10:48

回答

3

您可以使用List.map而不是List.iter,並返回元素不變。你會被重建列表:

let myList = 
    numbers 
    |> List.map square 
    |> List.map (fun x -> printfn "%d" x; x) 
    |> List.filter isOdd 
    |> List.map (fun x -> printfn "%d" x; x) 

另一種方法是,以代替separatly存儲每個元素,是整個列表存儲作爲函數參數:

let myList = 
    numbers 
    |> List.map square 
    |> (fun xs -> List.iter (printfn "%d") xs; xs) 
    |> List.filter isOdd 
    |> (fun xs -> List.iter (printfn "%d") xs; xs) 

最後一個變種,我可以想想,就是完全支流水線:

let myList = 
    numbers 
    |> List.map square 
    |> fun xs -> 
      xs |> List.iter (printfn "%d") 
      xs 
      |> List.filter isOdd 
      |> fun xs -> 
       xs |> List.iter (printfn "%d") 
       xs 
+3

您的第一個選項可以更漂亮用一個方法擴展List模塊,我會稱之爲'做'。那麼沒有必要記住要返回值。 'List.map square |> List.do(printfn「%d」)' – 2011-03-12 13:16:09

+1

我認爲最後一個變體是有點瘋狂的反模式。你只是在'let xs = in '' |> fun xs - >'這不是一個提供'let'關鍵字的語言的好主意:-)(這是純粹的一個很好的技巧lambda微積分雖然) – 2011-03-12 16:58:04