2015-10-01 1 views
0

Я знаю, что обсуждение функций и методов хорошо избито, поэтому я постараюсь быть кратким. Я хочу показать крошечный блок кода и получить обратную связь:Рекурсивная функция/метод Scala - поиск окончательного ответа на то, что это такое

  1. Это метод, функция, то и другое, что-то еще?
  2. Если это способ, можно ли его превратить в функцию? (кроме как по значению f = m _)
  3. Есть ли более идиоматические способы сделать то, что я пытаюсь в этом примере?

Когда я вижу документы на методы, которые мы видим следующее:

def m(a:Int, b:Int):Int = { a + b } 

В поисках функций мы видим:

(a:Int, b:Int) => a + b OR 
val f:(Int,Int) => Int = (a, b) => a + b 

Однако, когда мы копаться в recursive functions мы почти всегда видим:

@tailrec def countStrings(a:List[String], b:Int = 0):Int = { 
    if (a == Nil) b 
    else countStrings(a.tail, b + 1) 
} 
countStrings: (a: List[String], b: Int)Int 

Итак, на основе что я читал о методах, приведенный выше рекурсивный счетчик строк - это рекурсивный метод, а не функция. Теперь, если мы перепишем это в виде функции в соответствии с тем, как документы говорят нам, чтобы написать функции:

val countStrings:(List[String],Int) => Int = (a,b) => { 
    if (a == Nil) b 
    else countStrings(a.tail, b + 1) 
} 
countStrings: (List[String], Int) => Int = <function2> 

Так что мой вопрос именно так: Является ли следующий блок помечается @tailrec функцию, метод, как , или что-то другое?

@tailrec def countStrings(a:List[String], b:Int = 0):Int = { 
    if (a == Nil) b 
    else countStrings(a.tail, b + 1) 
} 

Кроме того, извинения, если это дубликат, я искал и, как и большинство вещей Скале, обнаружили противоречивые мнения по этому вопросу. Поэтому я надеюсь представить чрезвычайно простой пример и получить окончательный ответ. Спасибо.

+0

Неофициально термины взаимозаменяемы. Менее неофициально, 'def m' означает член, который имеет тип метода. Значение 'val f' может быть типа' Function', где значение может быть буквальным '_ => 42' или' m _' и т. Д. –

+0

Я верю, что ответ на ваш последний вопрос: это метод. Функции - это объекты с методом 'apply()', это не так. Вы можете изменить метод на функцию, используя расширение eta и afaik, есть два пути: сначала вы говорите «val f = m _», другое - «val f: Int => Int = m'. Поэтому, если компилятор знает, что ему нужна функция, он сможет расширять его без вашего явного подчеркивания. –

+0

Если вы измените 'countStrings()' так, чтобы он больше не был рекурсивным, компилятор сообщает нам: 'error: не удалось оптимизировать @tailrec annotated' ** method **' countStrings' – jwvh

ответ

0

Будучи точным, например, случай @tailrec def countStrings... является метод - не является функцией. В то время как преобразование в функцию или запись в виде функции возможно, рассматриваемый синтаксис может быть корректно назван методом.

0

Ваш пример tailrec называется методом в scala, а метод tailrec может применяться к методу, а не к функции.

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

Как вы упомянули в вашем вопросе, вы можете преобразовать ваш метод к функции, как это:

scala> countStrings _ 
res0: (List[String], Int) => Int = <function2> 

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

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