2013-03-08 4 views
10

В Scala почему-то, что каррическая функция может быть легко передана непосредственно другим функциям, но при назначении ей val необходимо также частично применить ее с помощью _? Например, если две функции:Почему Scala требует частичного применения карриных функций при назначении значения val?

def curried(a: Int)(b: Int) = a + b 
def test(a: Int, f: Int => Int) = f(a) 

можно легко пройти curried к test с:

test(5, curried(5)) 

и все довольны. Однако, если я просто называю curried(5) я получаю сообщение об ошибке:

scala> curried(5) 
<console>:9: error: missing arguments for method curried; 
follow this method with `_' if you want to treat it as a partially applied function 
       curried(5) 

Если я изменить вызов, чтобы включить информацию о типе, однако, это работает:

val 'curried: Int => Int = curried(5) 

Может кто-нибудь объяснить рационально за несогласованности, безусловно, Компилятор Scala может сделать вывод о том, что функция Int => Int с учетом определения типа исходного метода?

+0

В случае с «val», если вы даете аннотацию типа, вам не понадобится открытое частичное приложение '_'. –

ответ

8

Проблема заключается не в определении типа, проблема заключается в выводе ваших намерений. Вы допустили ошибку, или вы намеренно выполняли функцию?

Увы, задний синтаксис синтаксиса является формальным синтаксисом и опусканием его является синтаксический сахар.

+0

Это имеет смысл, но, безусловно, тот факт, что я уже описал метод как карри-функцию, уже описывал мое намерение. Если проблема заключается в выводе намерения, почему это нормально для inlining? –

+0

@MarkDerricutt Я не уверен, что вы подразумеваете под «inlining», но во всех случаях вы показали, где он работает, вы _declared_, что вы ожидали от него, поэтому Scala продолжает карри, потому что это соответствует вашему ожиданию. Что касается первого, Scala не выполняет неявно, он явно переопределяется с завершающим подчеркиванием или совпадением типов - если вы исходите из языка с неявным каррированием, который может показаться неестественным. Однако функция _declaration_ объявляет несколько списков параметров, что полезно для других вещей, кроме каррирования. –

+0

Под «inlining» я имел в виду использование в позиции аргумента (думая об этом, присваивание аргументу имеет полностью квалифицированную информацию о типе, так что по сути это то же самое, что и в моем последнем примере). Я предположил, что явное currying Scala исходит из нескольких списков аргументов, в отличие от подхода Haskell, где каждое объявление метода неявно отображается, и любой вызов с отсутствующими аргументами возвращает функцию curried в этой позиции. Мое замешательство исходит из предположения, что «несколько списков параметров == currying», очевидно, это не так. –

0

Подчеркивание не всегда необходимо. От http://docs.scala-lang.org/cheatsheets/

val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd 

выделки, очевидным синтаксисом.

def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd 

выделка, очевидно, синтаксис

def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd 

выделка, синтаксисом. но потом:

val normer = zscore(7, 0.4) _ 

необходимо отставая подчеркивание, чтобы получить частичное, только для сахарной версии.

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

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