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;;
我收到错误
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'.
为什么我无法退回号码?
答案 0 :(得分: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;;