2016-08-02 80 views
2

我搞亂了F#和寓言,並試圖測試我的理解。爲此,我試着創建一個函數來計算給定的迭代次數。我想出來的是F#:不理解匹配..與

let eCalc n = 
     let rec internalECalc ifact sum count = 
      match count = n with 
      | true -> sum 
      | _ -> internalECalc (ifact/(float count)) (sum + ifact) (count+1) 

     internalECalc 1.0 0.0 1 

工作正常,返回2.7182818284590455當

eCalc 20 

稱爲但是,如果我嘗試使用,我的想法是,更正確的形式

let eCalc n = 
     let rec internalECalc ifact sum count = 
      match count with 
      | n -> sum 
      | _ -> internalECalc (ifact/(float count)) (sum + ifact) (count+1) 

     internalECalc 1.0 0.0 1 

我得到一個警告「[警告]這個規則永遠不會匹配(L5,10-L5,11)」,並且返回值爲0.(並且如果我交換'n'和'count '在比賽聲明中)。在比賽聲明中我不能使用'n'是否有原因?有沒有辦法解決這個問題,所以我可以使用'n'?

感謝

回答

10

當您在match語句中使用的名稱,你檢查它在分配給該變量你覺得你的方式的價值。您改爲指定該名稱。即,

match someInt with 
| n -> printfn "%d" n 

將打印值爲someInt。這相當於let n = someInt; printfn "%d" n

你想要做的是使用when條款;在when子句中,您不是模式匹配的,但是在檢查時執行「標準」。所以你想要的是:

let eCalc n = 
     let rec internalECalc ifact sum count = 
      match count with 
      | cnt when cnt = n -> sum 
      | _ -> internalECalc (ifact/(float count)) (sum + ifact) (count+1) 

     internalECalc 1.0 0.0 1 

這是有道理的,還是你需要我進入更多的細節?

P.S.在像這樣的情況下,您的匹配函數看起來像「x when(布爾條件涉及x) - > case 1 | _ - > case 2」時,使用簡單的if表達式可讀性更高一些:

let eCalc n = 
     let rec internalECalc ifact sum count = 
      if count = n then 
       sum 
      else 
       internalECalc (ifact/(float count)) (sum + ifact) (count+1) 

     internalECalc 1.0 0.0 1 
+4

這是一個很好的解釋,所以upvote :)我認爲,一個更簡單,更習慣的解決方案,但是,將使用「if/then/else」表達式。 –

+0

是的,在這種情況下,「if/then/else」更好。我希望儘可能接近OP的原始代碼來說明差異,但我不妨編輯答案以顯示更好的方式。 – rmunn

+0

我認爲這樣可以顯示模式匹配語法,因此我會將它留在答案中,但也可能會添加* if/then/else'選項。 –