2013-10-13 93 views
4
let compareDiagonal p x y = 
    System.Math.Abs((int)(x - (fst p))) <> System.Math.Abs((int)(y - (snd p)));; 

let isAllowed p = function 
    | [] -> true 
    | list -> List.forall (fun (x, y) -> fst p <> x && snd p <> y && (compareDiagonal p x y)) list;; 

let rec solve col list = 
    let solCount : int = 0 
    match col with 
    | col when col < 8 -> 
     for row in [0 .. 7] do 
      solCount = solCount + if isAllowed (row, col) list then solve (col + 1) ((row, col) :: list) else 0 
     solCount   
    | _ -> 1;; 

let solCount = solve 0 [];; 
solCount;; 

我收到錯誤有什麼不對的F#代碼

solCount = solCount + if isAllowed (row, col) list then (solve (col + 1) ((row, col) :: list)) else 0 
------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

stdin(335,13): warning FS0020: This expression should have type 'unit', but has type 'bool'. If assigning to a property use the syntax 'obj.Prop <- expr'. 

爲什麼我不能夠返回多少?

回答

4

有兩個相關的問題。

默認情況下,F#變量是不可變的。如果你想有一個可變的變量,你必須聲明,就像這樣:

let mutable solCount : int = 0 

然後當你賦值給它,而不是使用=的,你必須使用<-這樣的:

solCount <- solCount + if isAllowed (row, col) list then solve (col + 1) ((row, col) :: list) else 0 

一個完整的例子遵循。

然而,這不是正確的功能方式來做這樣的事情。不要使用循環來累加值,而是使用遞歸函數來返回累積值。使用F#功能程序設計使用的方式幾乎總會產生更好的結果,儘管它需要一些習慣。

你原來的例子有可變的,而不是「功能性的方式」:

let compareDiagonal p x y = 
    System.Math.Abs((int)(x - (fst p))) <> System.Math.Abs((int)(y - (snd p)));; 

let isAllowed p = function 
    | [] -> true 
    | list -> List.forall (fun (x, y) -> fst p <> x && snd p <> y && (compareDiagonal p x y)) list;; 

let rec solve col list = 
    let mutable solCount : int = 0 
    match col with 
    | col when col < 8 -> 
     for row in [0 .. 7] do 
      solCount <- solCount + if isAllowed (row, col) list then solve (col + 1) ((row, col) :: list) else 0 
     solCount   
    | _ -> 1;; 

let solCount = solve 0 [];; 
solCount;; 
+2

另一種選擇是完全避免易變性和使用延續傳遞風格或蓄電池獲得尾遞歸函數 – devshorts

+0

另一個清潔重構可能包括將if語句作爲匹配移動到它自己的函數中,並使用兩個相互遞歸的函數。這樣可以消除求解函數中的嵌入式邏輯 – devshorts