2013-10-02 71 views
0

所以這是上下文。假設我有一個函數需要2個實驗的元組,並根據一系列規則進行測試。只要實驗元組通過一定的規則被正確驗證,函數應該停止。帶布爾值的F#遞歸

type exp = A | B | Mix of exp * exp | Var of string 

type sufficency = exp * exp 

type rule = Rule of sufficency * (sufficency list) 


let rec findout rules (exp1, exp2) = // return a boolean value 
      match rules with 
      | [] -> true 
      | thisRule::remaining -> 
       match thisRule with 
       | (suff, condition) -> 
        match suff with 
        | (fstExp, sndExp) -> 
         let map1 = unify Map.empty exp1 fstExp // I don't mention this function in here, but it is defined in my code 
         let map2 = unify Map.empty exp2 sndExp 
         true 
       findout remaining (exp1, exp2) 

的問題是,我不知道這到底是怎麼用這樣的函數式編程來完成。使用命令式編程,循環遍歷規則列表會更容易,而使用遞歸遍歷列表。

那麼應該在遞歸的每個階段的函數的返回?

我得到與該代碼的警告上述

警告FS0020:此表達式的類型應該是「單元」,但具有類型 「布爾」。使用'忽略'放棄表達式的結果,或'讓' 將結果綁定到名稱。

+0

您的'unify'代碼丟失。此外,'功能<>遞歸'。隨意使用'List.tryFind'和朋友。 –

+0

嗨,約翰,我沒有提到我的文章中的統一功能,但它是在我的代碼中定義的。 – user2431438

+1

而不是多個單例匹配語句,您可以一次解構列表的整個頭部:'| (((fstExp,sndExp),condition):: remaining - >'。另外它看起來像你的情況爲空列表應該返回'false',否則'findout'將始終返回true。 – Lee

回答

2

所以這樣你就得到一個警告的問題是在這部分代碼

  match thisRule with 
      | (suff, condition) -> 
       match suff with 
       | (fstExp, sndExp) -> 
        let map1 = unify Map.empty exp1 fstExp // I don't mention this function in here, but it is defined in my code 
        let map2 = unify Map.empty exp2 sndExp 
        true 
      findout remaining (exp1, exp2) 

第一match返回true。你可能想

  match thisRule with 
      | (suff, condition) -> 
       match suff with 
       | (fstExp, sndExp) -> 
        let map1 = unify Map.empty exp1 fstExp // I don't mention this function in here, but it is defined in my code 
        let map2 = unify Map.empty exp2 sndExp 
        true && findout remaining (exp1, exp2) 

你在哪裏通過計算攜帶true。但是,如果使用各種List.*函數,這可能會更簡單。