2017-10-15 67 views
2

簡單的問題。F#爲什麼我會得到這種返回類型?

我有一個函數,它需要兩個字符串和一個int,並返回一個新的字符串和n行,並在兩個輸入字符串之間交替。

let rec f s1 s2 n = function 
    | s1 when n > 0 -> s1 + "\n" + f s2 s1 (n-1) 
    | s2 when n > 0 -> s2 + "\n" + f s1 s2 (n-1) 

調用它

f "ab" "cd" 4 

應該返回ab\ncd\nab\ncd

目前,我得到一個錯誤,在我的方法,我不知道爲什麼。任何提示?

UPDATE:

事實證明,它是通過使用匿名function引起的。它改變到match表達解決它:

let rec f s1 s2 n = 
    match s1 with 
    | _ when n <= 0 -> "" 
    | s1 when n > 0 -> s1 + "\n" + f s2 s1 (n-1) 
    | s2 when n > 0 -> s2 + "\n" + f s1 s2 (n-1) 

更新2:上述功能可能是在正確方向邁出的一步,但下面的實施是通過TheQuickBrownFox指出正確的。

let rec f s1 s2 n = 
    if n <= 0 then "" 
    else s1 + "\n" + f s2 s1 (n-1) 
+0

我更新了你的更新後的答案。 – TheQuickBrownFox

回答

3

function關鍵字的一個參數就創建了一個新的匿名函數(或lambda),並直接進入模式匹配。

所以你的f功能需要s1,s2n,然後返回另一個函數作爲值。這是一樣寫這:

let rec f s1 s2 n = 
    fun x -> 
     match x with 
     | s1 when n > 0 -> s1 + "\n" + f s2 s1 (n-1) 
     | s2 when n > 0 -> s2 + "\n" + f s1 s2 (n-1) 

這不是我清楚你的函數試圖這樣做,我不能建議你修復。我建議暫時遠離function關鍵字。嘗試以這種形式寫這個功能,看看是否有幫助:

let rec f s1 s2 n = 
    match ... with 
    ... 

UPDATE:

在更新的實現,你沒有實際使用模式的所有匹配。模式部分被有效地丟棄,並且when子句正在完成所有的工作。此外,由於要麼n <= 0要麼n > 0,因此不可能達到最後的分支。你的新功能可以寫得更簡單:

let rec f s1 s2 n = 
    if n <= 0 then "" 
    else s1 + "\n" + f s2 s1 (n-1) 
+0

每次有人發佈F#問題時都會收到通知嗎? :p – Khaine775

+1

是的。如果您將鼠標懸停在標籤上,您可以通過電子郵件訂閱該標籤:) – TheQuickBrownFox

+0

我可以使用您關於省略函數關鍵字的建議來找到正確的解決方案。 – Khaine775

相關問題