Я изучаю Скалу, работая над упражнениями из книги «Скала для нетерпимого». Есть несколько вопросов, которые проверяют концепцию каррирования. Я ответил им наилучшим образом, но я хотел бы запустить их экспертами.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
}
'isCorrespondingLength' компилируется с символом подчеркивания, но' myCorresponds' этого не делает. 'arr.zip (that) .find (f) .isDefined' или' arr.zip (that) .find (p => f.apply (_, _)). isDefined' не компилируется. –
В первом случае 'f' должна быть функцией, которая принимает один аргумент' (String, Int) 'для его компиляции вместо двух аргументов; во втором 'p => f.apply (_, _)' просто не то, что вы хотите (это эквивалентно 'p => {(q, r) => f.apply (q, r)}'. Но разница между ними и рабочей версией в вашем вопросе не выглядит. –