"这个表达式应该有类型单位"但我希望它是布尔值

Jav*_*ini 2 f# types tuples unit-type

我正在尝试创建一个函数,将元组与元组数组的值进行比较.我需要这个返回一个布尔值,但是VS2013一直告诉我:"这个表达式应该有'unit'类型,但是类型'bool'"

let compare (i,j,a,(x : (int*int*int) array)) =
    for q in 0 .. x.GetLength(0) do  
        match (i,j,a,x) with
        | (i,j,a,x) when (i,j,a) = x.[q] -> true
        |  _ -> false
Run Code Online (Sandbox Code Playgroud)

还尝试将值作为两个参数给出,但它也不起作用:

let compare (i,j,a) (x : (int*int*int) array) =
    for q in 0 .. x.GetLength(0) do  
        match (i,j,a) with
        | x.[q] -> true
        |  _ -> false
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激!

Tom*_*cek 7

为了扩展一点Chris的答案,你的代码不起作用的主要原因是F#是一种基于表达式的语言,并且没有你可能期望的命令式控制流(如果你读错了)表达式的主体为return关键字).

由于F#是基于表达式的,因此所有内容都是一个计算结果值的表达式.所以,true是一个计算结果为true(布尔值)的表达式.您的示例中的模式匹配:

match (i,j,a,x) with
| (i,j,a,x) when (i,j,a) = x.[q] -> true
|  _ -> false
Run Code Online (Sandbox Code Playgroud)

...也是一个表达式,根据变量的值来计算truefalse(布尔值).在这种情况下,条件会更简单:

if (i,j,a,x) = x.[q] then true else false
Run Code Online (Sandbox Code Playgroud)

......或者你可以写出(i,j,a,x) = x.[q]完全相同的条件.现在,for循环是棘手的,因为它多次评估主体,因此它可能会获得多个返回值.因此,F#有一个特殊类型unit(void在C#中思考),它表示不携带任何信息的值.所以,for循环期望 - unit回复身体像:

for i in 1 .. 10 do 
  printfn "Foo"
Run Code Online (Sandbox Code Playgroud)

您可以printfn "Foo"通过编写以下方式检查实际返回单位值:

for i in 1 .. 10 do 
  let nothing = printfn "Foo"
  nothing
Run Code Online (Sandbox Code Playgroud)

如果你将鼠标指针放在上面nothing,你会发现它是类型的unit.

因此,for如果你想在中间打破迭代,循环不是一个好方法(因为它不能在F#中完成).正如Chris和Søren已经提到的,您可以使用Array模块中的函数轻松实现逻辑.或者,你必须使用递归或可变变量来编写它 - 但Array模块在这里工作得很好.