types - 为什么这些参数被推断为具有单位类型?

标签 types f# unit-type

我故意将 x 添加到这个函数的末尾

let myMax x y =
  if x > y then x else y
  x

我原以为 x 和 y 参数仍然是“a 类型”,但我得到了这个签名:

myMax : x:unit -> y:unit -> unit

为什么这些参数被推断为具有单位类型?

编辑: 谢谢@gilles 的回答。考虑这两个函数:

let foo x y =
  0              // warning
  x
val foo : x:'a -> y:'b -> 'a

let foo2 x y =
  if x > y then x else y   // no warning
  x
val foo2 : x:unit -> y:unit -> unit

两个签名有何不同? 似乎在第二个函数中,编译器将比较结果解释为 x 或 y 作为单位

最佳答案

让我们写一个更简单的例子:

> fun x -> x; 0;;          
val it : unit -> int = <fun:clo@5>

在复合表达式中,分号/换行符之前的表达式必须具有单位类型。如果您想使用具有“真实”值的表达式(即除单位之外的任何类型),您需要显式忽略它,或将其绑定(bind)到无变量模式。如果表达式的类型不能与unit统一,编译器会提醒您:

> fun x -> 0; x;;

  fun x -> 0; x;;
  ---------^

stdin(7,10): warning FS0020: This expression should have type 'unit', but has type 'int'. 
Use 'ignore' to discard the result of the expression, 
or 'let' to bind the result to a name.
val it : x:'a -> 'a = <fun:clo@7-1>

可以有一个类型规则,允许 ; 之前的任何类型 - 毕竟该值会被忽略,因此它的类型并不重要 - 但这很容易导致意外丢弃重要的返回值。因此,如果您想忽略该值,请明确执行:

let myMax x y =
  ignore (if x > y then x else y)
  x

let myMax x y =
  let _ = if x > y then x else y
  x

关于types - 为什么这些参数被推断为具有单位类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37093957/

相关文章:

.net - F# 如何捕获所有异常

.net - F#:函数中有更多返回点,如何处理?

Java 泛型 : How to specify a Class type for a generic typed class?

C# 等同于 TypeScript 模板文字类型?

types - 如何在 TypeScript 中注释递归类型?

f# - 为什么我不能用 Paket 添加包?

list - 如何将 `n` 表示为一系列数字

azure - FSharp.Data.SqlClient "Method Not Found"

struct - 创建零大小结构的多种方法有什么区别?

f# - 此表达式的类型应该为 'unit',但类型为 'ConsoleKeyInfo'