2017-10-18 112 views
2

我正在致力於一個簡單的函數,應該給出x,返回一個元組(y, z),使得y <= abs(5) + z * 10 = x,其中z最小的可能值。功能增量

在C中,我會遍歷z++y++,直到它們的總和匹配x

目前,我正試圖在功能上解決這個問題。請考慮以下示例:

let foo x = 
    let rec aux (y, z, q) = 
     match (y + z * 10) with 
     q  -> (y, z) 
     |_  -> aux(y + 1, z + 1, q) //How to correctly set the increments? 
    aux(0, 0, x) 

無論如何,此方法始終返回(0, 0)。我提到this question,同時考慮解決方案。我知道應該避免可變變量,這就是我所做的。不幸的是,我擔心我在某個地方錯過了這個觀點,因此我從錯誤的方面接近了這個問題。

回答

4

您正在引入一個新的q綁定,用於在第一個匹配項中評估的表達式的結果,而不是與其進行比較。你想要的是這樣的:

match (y + z * 10) with 
| r when r = q -> (y, z) 
| _ -> aux(y + 1, z + 1, q) 
+0

明白了,謝謝。 – Worice

1

在F#中,你通常是在一個值表達式或模式匹配表達式。當你這樣做:

match (y + z * 10) with 
q  -> (y, z) 

你實際上是說:「計算y + z * 10,然後將結果總是分配給一個新的變量q,忽略這個新的變量,並返回(y, z)」。這是因爲q是在模式匹配表達式中編寫的,因爲它只是在with之後。

這也是爲什麼你在下一行說「這個規則永遠不會匹配」的原因。當人們學習F#時,這是一個非常常見的誤解。

當你這樣做時,你並沒有真正使用模式匹配。因此,我建議使用if表達式來代替:

 if y + z * 10 = q 
     then (y, z) 
     else aux (y + 1, z + 1, q) 

這實際上等同於使用三元運營商?:在C,因爲它是一個表達式,而不是語句,但它讀取更加清晰。

+0

非常感謝您的解釋,它幫助我更清晰地理解了這個概念。 – Worice