F#If/Then中的推断类型

F#If/Then中的推断类型,f#,type-inference,unit-type,F#,Type Inference,Unit Type,如果我有以下功能: let myFunc x y = if y = 0 then 1 x 我得到一个错误: Program.fs(58,17): error FS0001: This expression was expected to have type unit but here has type int 为什么编译器希望在F中使用“unit”而不是int?当使用if语句时,如果没有else分支,那么它会隐式返回unit。如果您的,则分支返回的类型

如果我有以下功能:

let myFunc x y =
  if y = 0 then 1
  x
我得到一个错误:

Program.fs(58,17): error FS0001: This expression was expected to have type
    unit    
but here has type
    int    
为什么编译器希望在F中使用“unit”而不是int?

当使用
if
语句时,如果没有
else
分支,那么它会隐式返回
unit
。如果您的
,则
分支返回的类型不是
单元
,您必须有一个显式的
else
分支才能正常工作。在您的示例中,您可以编写:

let myFunc x y = if y = 0 then 1 else x

MSDN-

值得补充的是,这不仅仅是
if
的属性。F#是一种基于表达式的语言,这意味着几乎每段代码(除了类型声明和少数例外)都是一个计算结果的表达式。事实上,F#不调用if语句,而是调用if表达式

这意味着您可以在意外的地方使用
if
。例如,这可能很有用:

x/2 + (if x%2=0 then 0 else 1) 
正如Garry已经解释的那样,如果省略
else
,那么表达式仍然需要返回一些东西-如果结果是
int
,那么它就没有意义(编译器应该选择哪个数字?),因此它要求结果的类型为
unit
,这是表示“没有结果”

单元
类型也是所有命令函数(例如
printf
)或所有逻辑上不返回任何值的表达式(赋值或循环)的结果。这意味着如果您写入:

if x > 0 then printfn "Big!"
…那么表达式类型正确,因为
printfn“大!“
有一个返回类型
unit
,隐式添加的
else
分支也返回
unit
。您可以直接手动创建
unit
类型的值(该类型正好有一个值),因此上述实际上对应于:

if x > 0 then printfn "Big!" else ()
从C#的角度来看,将
if..then..else
读作条件运算符更有意义:

x/2 + (x%2 == 0 ? 0 : 1)

如果你把这个标记为<代码>,如果语句是在告诉你,在f*,<代码>如果< /代码>是一个表达式。:-谢谢Snpe。@ ILJJARN,F f可以考虑<代码>如果< /COD>一个表达式,其他语言没有。有一个标签只是为了F的理解<代码>如果< /代码>可能会引起其他人的混乱。