2013-05-22 2 views
0

Я пытаюсь понять, почему моя функция curries работает следующим образом. Я построил функцию , чтобы обеспечить, чтобы использовать более функциональный подход вместо нескольких операторов if-then, которые будут выполнять одно и то же.Функция Curried оценивает все аргументы

Я обнаружил, что ошибка сегодня проведет некоторые тесты, где, если условие в первом случае обеспечит функцию, например. обеспечить (содержание.hasNext & & acc! = Null) истинно, ложное условие или второе утверждение все еще оценивается и становится главной функцией.

я могу решить эту проблему, если я просто изменить это: обеспечения (contents.hasNext) к этому: обеспечения (contents.hasNext & & акк == NULL), но я борюсь с тем, почему это происходит ,

Есть ли более очевидное (или просто лучшее) решение?

def ensure[T](f: => Boolean)(truth: => T, lie: T) = if (f) truth else lie 


    def lines(): Stream[String] = { 
    def matchLine(text: String, acc: String): Stream[String] = text match { 
     ... 
     case NewLine(string) => 
     ensure(contents.hasNext && acc != null)(acc +: matchLine(contents.next, string), 
      ensure(contents.hasNext)(matchLine(contents.next, string), acc +: string +: empty)) 
     ... 
    } 
    ensure(contents.hasNext)(matchLine(contents.next, null), empty) 
    } 
+0

Если вы действительно хотите оценить условие и вызвать одну из двух возможных функций по имени (один для true, другой для false), вы должны изучить «Scalaz». У этого есть метод 'fold', который получает pimped на boolean, чтобы сделать именно то, что Вы здесь делаете. – cmbaxter

ответ

3
(truth: => T, lie: T) 

Это означает, что выражение, приведенное для параметра truth, будет оцениваться каждый раз, когда truth используется в вашей функции (и только тогда), в то время как lie будет выполняться только один раз перед началом вашей функции выполнения. Другими словами: truth передается по имени и lie нет. Чтобы добиться желаемого поведения, вам нужно пройти как по имени (с другой стороны, условие по имени не обязательно необходимо, так как оно будет оцениваться ровно один раз в начале функции во всех случаях):

ensure[T](f: Boolean)(truth: => T, lie: => T) = if (f) truth else lie 

Это не означает, что замена выражений if-then-else функцией, которая в основном является оболочкой if-then-else, делает ваш код более функциональным.

+0

Спасибо! Это работает. – comamitc

Смежные вопросы