Отсутствует тип параметра для расширенной функции при создании частично примененной функции
Я новичок в Scala и читал о частично примененных функциях в Scala. У меня есть общая функция "обтекание", которая может объединять три строки.
def wrap(prefix: String)(html: String)(suffix: String) = prefix + html + suffix
Когда я пытаюсь сделать специализированную функцию, как это
val foo = wrap(_)("Hello")(_)
Сбой с ошибкой пропущенного типа параметра, но работает, если я предоставляю тип для первого аргумента, например
val foo = wrap(_:String)("Hello")(_)
Мои вопросы:
Почему я должен предоставлять тип избыточно? Я уже предоставил это в общем определении обтекания.
Почему для последнего аргумента не требуется тип?
2 ответа
Например, компилятор Scala не всегда может определить типы: подумайте о перегруженных методах, когда компилятор не может знать, на какой из них вы ссылаетесь.
def wrap(prefix: String)(html: String)(suffix: String) = prefix + html + suffix
def wrap(prefix: Int)(html: String)(suffix: String) = prefix.toString + html + suffix
val foo = wrap(_: String)("Hello")(_: String)
val foo1 = wrap(_)("Hello")(_) // compilation Error: Cannot resolve method 'wrap'
Итак, вам нужно явно указать параметр типа, как показано ниже:
val foo = wrap(_: String)("Hello")(_: String)
val foo1 = wrap(_: Int)("Hello")(_: String)
или укажите тип возврата явно:
val foo: (String, String) => String = wrap(_)("Hello")(_)
val foo1: (Int, String) => String = wrap(_)("Hello")(_)
Как вы обнаружили, вам нужно дать компилятору немного больше информации о типах, прежде чем он сможет определить тип foo
, Вы можете указать типы аргументов:
val foo = wrap(_: String)("Hello")(_: String)
или тип результата
val foo: (String, String) => String = wrap(_)("Hello")(_)
Указание одного типа не компилируется в моей сборке с использованием 2.12.7
val foo = wrap(_: String)("Hello")(_) // Does not compile