为什么函数签名具有跟随其他参数的单位参数?

时间:2015-12-06 14:05:02

标签: f# unit-type

我正在查看我在培训课程中看到的一项功能,并且无法理解在以下功能结束时使用“()”:

let acclock (start:DateTimeOffset) rate () =
    let now = DateTime.Now
    let elapsed = now - start
    start.AddTicks (elapsed.Ticks * rate)

为什么函数签名在其签名的其他参数的末尾有一个单位参数?

因此,我认为单位参数不代表任何参数或返回类型,类似于“void”。

2 个答案:

答案 0 :(得分:7)

这与部分申请有关。您可以将此函数绑定到另一个名称,同时提供startrate参数,创建类型为() -> DateTime的函数。只有在调用该函数时,才会执行“elapsed = now - start”和“start.AddTicks”的计算。像这样:

let timeThis =
    let stopClock = acclock DateTime.Now 500
    doStuff ()
    stopClock () // The function is only executed now

如果最后没有()参数,则在添加rate值时直接执行该语句。

let acclock' (start:DateTimeOffset) rate =
    let now = DateTime.Now
    let elapsed = now - start
    start.AddTicks (elapsed.Ticks * rate)

let timeThis1 =
    let stopClock = acclock' DateTime.Now
    doStuff ()
    stopClock 500 // This is only executed now

// Or
let timeThis2 =
    let stopClock = acclock' DateTime.Now 500 // Wait, we calculated it immediately
    doStuff ()
    stopClock // This is just a value

答案 1 :(得分:4)

使用额外的(),您可以传递startrate个参数,并获得部分应用的函数unit -> DateTime

let partiallyAppliedAcclock = acclock DateTime.Now 1L

val partiallyAppliedAcclock : (unit -> System.DateTime)

如果没有(),则为DateTime值。

let acclockValue = acclock2 DateTime.Now 1L // acclock defined without ()

val acclockValue : DateTime = 06-12-15 3:20:41 PM

差异对于纯函数并不重要(您总是可以用纯值替换对纯函数的调用),但acclock不纯。它使用DateTime.Now,因此每次调用时结果都会不同。