【问题标题】:F#: This expression was expected to have type DateTime but here has type unitF#:此表达式应为 DateTime 类型,但此处为 unit 类型
【发布时间】:2018-05-03 08:01:33
【问题描述】:

以下 F# 函数无法编译

open System
let checkCreation time : DateTime = 
    if (time > DateTime.UtcNow.AddDays(-7.0)) then printfn "New"
    else printfn "Old"

checkCreation time

错误标记指向“新”和“旧”

编译器失败并出现以下错误:

Script1.fsx(3,59):错误 FS0001:此表达式应具有类型

DateTime    

但是这里有类型

unit    

当我试图通过 printfn 打印某些内容时,为什么编译器需要 DateTime?

【问题讨论】:

  • 您可以从方法签名中删除: DateTime,让编译器为您推断类型。目前因为它,编译器认为您将从函数中返回DateTime。但是你没有返回任何东西。

标签: f#


【解决方案1】:

替换这个

let checkCreation time: DateTime = 

有了这个

let checkCreation (time: DateTime) = 

第一个具有签名(DateTime -> DateTime),因为您明确地对函数输出进行了此约束。输入已被编译器推断出来。

第二个有签名(DateTime -> unit)。输入已被显式约束,输出unit推断

添加:

完整的显式签名应如下所示

let checkCreation (time: DateTime) : unit = 
    ...

您可以删除每个显式类型约束并让编译器完成工作:

//because time argument compared to DateTime it is inferred to be DateTime
//No explicit constrain needed
let checkCreation time = //DateTime -> unit

    //because if expression is the last one, its output will be used as function output
    if (time > DateTime.UtcNow.AddDays(-7.0))
    //because then branch has unit output, function output will be inferred as unit
    then printfn "New" 
    //else branch output MUST match with then branch. Your code pass :)
    else printfn "Old"

【讨论】:

  • 谢谢。有用。我是否正确理解没有括号,: DateTime 指的是返回值?和他们一起,它指的是输入参数?
  • @urig 我已经添加了一些解释
  • @urig 我对 F# 也比较陌生。我发现最好先让编译器尝试自己找出类型,如果失败,只添加显式注释。 (而且我认为更多有经验的人会同意这一点。)
  • @urig 它还有助于知道表示函数应用程序的空格(或任何类型的并置)具有最高优先级,超过所有二进制运算符,包括 :,这就是编译器粗略解析您的代码的原因如果省略括号,则为 (checkCreation time): DateTime
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多