2014-08-27 5 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

1

Я не совсем понимаю ваш вопрос. Код явно не компилируется.

DetermineTargettedEnrollmentDate определяется как

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

Что значит, она принимает два параметра: EnrollmentPeriod и DateTime и возвращает другую DateTime. Позже в ProjectDaysWorkedSinceJan1 использовать его только с одним аргументом:

let targettedEnrollmentDate = DetermineTargettedEnrollmentDate targettedEnrollmentPeriod 

Из-за partial application, это делает targettedEnrollmentDate функция, которая принимает DateTime и вернуть другой DateTime. Но позже вы пытаетесь использовать его, как если бы это было значение, когда вы пытаетесь вычесть из него еще один DateTime.

 | Active -> int (januaryFirst - targettedEnrollmentDate).TotalDays 
    ----------------------------------^ 

(...) 

Possible overload: 'DateTime.op_Subtraction(d1: DateTime, d2: DateTime) : TimeSpan'. Type constraint mismatch. The type 
    DateTime -> DateTime  
is not compatible with type 
    DateTime  

То, что вы, вероятно, хотите, чтобы позвонить DetermineTargettedEnrollmentDate с relativeDate вместо:

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 
Смежные вопросы