2015-06-03 5 views
1

Я изучаю Скалу, работая над упражнениями из книги «Скала для нетерпимого». Есть несколько вопросов, которые проверяют концепцию каррирования. Я ответил им наилучшим образом, но я хотел бы запустить их экспертами.Scala: currying concept

сделать вызов corresponds, который проверяет, является ли элементы в массиве строк имеют длину, указанную в массиве целых чисел.

Мой код:

def isCorrespondingLength(arr: Array[String], len: Array[Int]) = { 
    arr.corresponds(len)(_.length == _) 
} 

Реализовать corresponds без выделки. Затем попробуйте выполнить вызов из предыдущего упражнения . С какой проблемой вы сталкиваетесь?

Ans: Компилятор не может получить тип, используя символы подчеркивания, как в предыдущем упражнении.

def myCorresponds(arr: Array[String], that: Seq[Int], f: (String, Int) => Boolean) = { 
    arr.zip(that).find(p => f.apply(p._1, p._2)).isDefined 
} 

Реализовать абстракцию unless управления, который работает точно так же, как if, но с перевернутым состоянием. Должен ли первый параметр быть параметром call-by-name ? Вам нужно карри?

Ans: Первым параметром необязательно должен быть параметр для вызова по имени. Поскольку он оценивается только один раз, независимо от того, происходит ли оценка на сайте вызова (как в случае по умолчанию) или внутри функции (по вызову), это не влияет на результат. Currying, как и в unless2, обеспечивает отличную абстракцию управления unless2(false) { block }, но это необязательно.

def unless(condition:() => Boolean, block: => Boolean): Boolean = { 
    if (!condition()) block else false 
} 

def unless2(condition: => Boolean)(block: => Boolean): Boolean = { 
    if (!condition) block else false 
} 

ответ

0
def isCorrespondingLength(arr: Array[String], len: Array[Int]) = { 
    myCorresponds(arr, len, _.length == _) 
} 

отлично компилируется. Теперь рассмотрим, что произойдет, если вы сделаете myCorresponds generic (т. Е. Работаете с A и B, а не с String и Int).

+0

'isCorrespondingLength' компилируется с символом подчеркивания, но' myCorresponds' этого не делает. 'arr.zip (that) .find (f) .isDefined' или' arr.zip (that) .find (p => f.apply (_, _)). isDefined' не компилируется. –

+0

В первом случае 'f' должна быть функцией, которая принимает один аргумент' (String, Int) 'для его компиляции вместо двух аргументов; во втором 'p => f.apply (_, _)' просто не то, что вы хотите (это эквивалентно 'p => {(q, r) => f.apply (q, r)}'. Но разница между ними и рабочей версией в вашем вопросе не выглядит. –

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

  • Нет связанных вопросов^_^