2014-08-27 80 views
2

在下面的示例中,我收到错误“没有与方法'op_Subtraction'匹配的重载”。传递函数作为F#中的参数

open System 

type EmployeeStatus = 
    | Active 
    | NotActive 

type EnrollmentPeriod = 
    | JanuaryFirst 
    | JulyFirst 
    | PeriodNotApplicable 

let DetermineTargettedEnrollmentDate targettedEnrollmentDate (relativeDate : DateTime) = 
    match targettedEnrollmentDate with 
    | EnrollmentPeriod.JanuaryFirst -> new DateTime(relativeDate.Year + 1,1,1) 
    | EnrollmentPeriod.JulyFirst -> new DateTime(relativeDate.Year,7,1) 
    | EnrollmentPeriod.PeriodNotApplicable -> relativeDate 

let ProjectDaysWorkedSinceJan1 employeeStatus targettedEnrollmentPeriod (relativeDate : DateTime) = 
    let januaryFirst = DateTime(relativeDate.Year,1,1) 
    let targettedEnrollmentDate = DetermineTargettedEnrollmentDate targettedEnrollmentPeriod 
    match employeeStatus with 
    | Active -> int (januaryFirst - targettedEnrollmentDate).TotalDays 
    | NotActive -> 0 

它似乎不喜欢targettedEnrollmentDate正在由DetermineTargettedEnrollmentDate函数确定。

我在哪里错了?

回答

4

你仅与第一个参数供给DetermineTargettedEnrollmentDate

let targettedEnrollmentDate = DetermineTargettedEnrollmentDate targettedEnrollmentPeriod 

的该结果是等待第二参数的函数,即targettedEnrollmentDate是一个函数,它relativeDate作为参数。

所以,你试着做的是从日期中减去一个函数,这就是编译器所抱怨的。

+0

哈,这将是是一个很好的例子太接近代码。我一直盯着这个项目很久,我开始怀念这样的东西。感谢您的简洁回答! – Joe 2014-08-27 22:44:14

1

我真的不明白你的问题。代码显然不能编译。

DetermineTargettedEnrollmentDate被定义为

val DetermineTargettedEnrollmentDate : 
    targettedEnrollmentDate:EnrollmentPeriod -> 
    relativeDate:DateTime -> DateTime 

这意味着,它需要两个参数:一个EnrollmentPeriodDateTime并返回另一个DateTime。后来在ProjectDaysWorkedSinceJan1你只有一个参数中使用它:

let targettedEnrollmentDate = DetermineTargettedEnrollmentDate targettedEnrollmentPeriod 

因为partial application的,这使得targettedEnrollmentDate一个函数,该函数DateTime和返回另一个DateTime。但是当你尝试减去另一个DateTime时,你会尝试使用它,就好像它是一个值。

​​

你可能想要的是调用DetermineTargettedEnrollmentDaterelativeDate代替:

let ProjectDaysWorkedSinceJan1 employeeStatus targettedEnrollmentPeriod (relativeDate : DateTime) = 
    let januaryFirst = DateTime(relativeDate.Year,1,1) 
    let targettedEnrollmentDate = DetermineTargettedEnrollmentDate targettedEnrollmentPeriod relativeDate 
    match employeeStatus with 
    | Active -> int (januaryFirst - targettedEnrollmentDate).TotalDays 
    | NotActive -> 0 

这使得它具有以下结果编译:

val ProjectDaysWorkedSinceJan1 : 
    employeeStatus:EmployeeStatus -> 
    targettedEnrollmentPeriod:EnrollmentPeriod -> relativeDate:DateTime -> int