我有一個函數A類似於這個,它將一個函數B應用到目錄中的每個文件。每個文件都有一定數量的「條目」;函數B將當前的條目總數作爲參數,並返回在當前文件中找到的新條目的數量。如何讓這段代碼更具慣用的F#?
此外,我需要統計處理的文件數,並在每次處理文件時顯示此計數。由於我的命令背景,我想出了2個可變變量和一個for循環。
所以,有幾個問題:
- 我怎麼可以這樣寫的更地道,實用的風格?
- 你可以解釋一個更習慣解決方案的優點嗎?我很新功能編程 ,有時我看不出有什麼不對 與我的循環髒必要。
我有一個函數A類似於這個,它將一個函數B應用到目錄中的每個文件。每個文件都有一定數量的「條目」;函數B將當前的條目總數作爲參數,並返回在當前文件中找到的新條目的數量。如何讓這段代碼更具慣用的F#?
此外,我需要統計處理的文件數,並在每次處理文件時顯示此計數。由於我的命令背景,我想出了2個可變變量和一個for循環。
所以,有幾個問題:
這裏有更多的功能例如:
let files = Directory.EnumerateFiles sourceDirectory
let numFiles = Seq.length files
files
|> Seq.mapi (fun idx file -> (idx,file)) // Get access to the index in a loop
|> Seq.fold (fun numentries (index,file) ->
printfn "done %d of %d" index numFiles
numentries + (processFile file numFiles)
) 0
通過使用mapi
我能夠獲得訪問索引的循環,消除第一可變變量。第二個是通過使用fold
跟蹤文件的總數而不是可變變量來消除的。
這樣做的主要優點是沒有任何可變狀態,可以更容易地將代碼轉換爲在多個線程中運行。另外,由於變量是不變的,因此代碼的推理變得更簡單。
謝謝。我修復了一些有點誤導性的代碼,錯過了一個聲明:你能否更新你的答案以反映它? fileCounter(實際上是numEntries)與numFiles不同。 numFiles是目錄中的文件總數,用於打印「done x out numFiles」。 fileCounter(重命名爲numEntries)是在文件中找到的條目的總數。 – Asik 2012-07-25 02:23:14
@Dr_Asik - 已更新 – 2012-07-25 02:41:49
接受您的回答後,您至少應該編輯它。 ; - ](提示 - '目錄。EnumerateFiles'不返回數組。) – ildjarn 2012-07-25 22:31:23
假設你最終後是是numEntries
終值,那麼這是我的看法:
let getNumEntries sourceDirectory =
Directory.GetFiles sourceDirectory
|> fun files -> (0, 0, files.Length), files
||> Array.fold (fun (index, numEntries, numFiles) file ->
printfn "done %d of %d" index numFiles
index + 1, numEntries + processFile file numEntries, numFiles)
|> fun (_,numEntries,_) -> numEntries
如果你之後processFile
是副作用,而不是最終的numEntries
值的時候,然後用ignore
代替fun (_,numEntries,_) -> numEntries
。
你能解釋的優勢,以更地道的解決方案?我對函數式編程非常陌生,有時候我看不出循環中的髒命令有什麼問題。
除了主觀,這是相當廣泛的,並已在其他多個答案更徹底地回答比我在這裏可以做的。
該函數實際返回單位:「processFile」將所有有用的工作作爲副作用(將條目寫入磁盤)。 我的問題不是一般的函數式編程,而是特定的代碼片段。我知道一般的想法,但我試圖找到具體的例子來推動這一點。當然,爲什麼這7行代碼比我的9行代碼更好,這並不是一個太寬泛的問題。 – Asik 2012-07-25 02:57:52
@Dr_Asik:如果你想讓函數返回'unit',那麼用'ignore'替換fun(_,numEntries,_) - > numEntries'。即使問這個特定的代碼和你發佈的代碼的範圍並不是太廣泛,它肯定是主觀的,根據定義它不適合SO。無論如何,就像我說的那樣,在回答你所問的問題上有幾十個答案,更不用說其他數千篇在線文章了。 – ildjarn 2012-07-25 03:00:10
這對於[CodeReview.SE](http://codereview.stackexchange.com/)更合適。無論如何,'fileCounter'聲明在哪裏,爲什麼最終將'unit'分配給'files'? (是'文件'打算成爲一個函數嗎?) – ildjarn 2012-07-25 02:01:23
對不起格式是誤導和fileCounter聲明丟失。我編輯了代碼來解決這個問題。 – Asik 2012-07-25 02:19:43