Какой смысл в множественных предложениях параметров в определениях функций в Scala? - PullRequest
9 голосов
/ 02 сентября 2011

Я пытаюсь понять суть этой языковой особенности множественных предложений параметров и почему вы должны ее использовать. Например, в чем разница между этими двумя функциями на самом деле?

class WTF {
    def TwoParamClauses(x : Int)(y: Int) = x + y
    def OneParamClause(x: Int, y : Int) = x + y
}

>> val underTest = new WTF
>> underTest.TwoParamClauses(1)(1) // result is '2'
>> underTest.OneParamClause(1,1) // result is '2' 

Что-то есть в спецификации Scala в пункте 4.6 . Посмотри, имеет ли это для тебя смысл.

Примечание: спецификация называет эти «предложения параметров», но я думаю, что некоторые люди могут также называть их «списками параметров».

Ответы [ 5 ]

9 голосов
/ 02 сентября 2011

Вот три практических использования нескольких списков параметров,

  1. Чтобы помочь вывод типа. Это особенно полезно при использовании методов более высокого порядка. Ниже параметр типа A из g2 выведен из первого параметра x, поэтому аргументы функции во втором параметре f могут быть исключены,

    def g1[A](x: A, f: A => A) = f(x)
    g1(2, x => x) // error: missing parameter type for argument x
    
    def g2[A](x: A)(f: A => A) = f(x)
    g2(2) {x => x} // type is inferred; also, a nice syntax
    
  2. Для неявных параметров. Только последний список параметров может быть помечен как неявный, а один список параметров не может смешивать неявные и неявные параметры. Для определения g3 ниже требуется два списка параметров,

    // analogous to a context bound: g3[A : Ordering](x: A)
    def g3[A](x: A)(implicit ev: Ordering[A]) {}
    
  3. Чтобы установить значения по умолчанию на основе предыдущих параметров,

    def g4(x: Int, y: Int = 2*x) {} // error: not found value x
    def g5(x: Int)(y: Int = 2*x) {} // OK
    
8 голосов
/ 02 сентября 2011

TwoParamClause включает два вызова метода, тогда как OneParamClause вызывает метод function только один раз.Я думаю, что вы ищете термин карри .Среди множества вариантов использования он помогает разбить вычисление на маленькие шаги.Этот ответ может убедить вас в полезности карри.

6 голосов
/ 02 сентября 2011

Существует разница между обеими версиями относительно вывода типа. Рассмотрим

def f[A](a:A, aa:A) = null
f("x",1)
//Null = null

Здесь тип A связан с Any, который является супертипом String и Int. Но:

def g[A](a:A)(aa:A) = null
g("x")(1)

error: type mismatch;
 found   : Int(1)
 required: java.lang.String
       g("x")(1)
              ^

Как видите, средство проверки типов учитывает только первый список аргументов, поэтому A связывается с String, поэтому значение Int для aa во втором списке аргументов является ошибкой типа.

4 голосов
/ 02 сентября 2011

Несколько списков параметров могут помочь в определении типа scala для получения более подробной информации, см. Максимальное использование (чрезвычайно ограниченного) вывода типа Scala

Информация о типе не перемещается слева направо в списке аргументов , только из слева направо по спискам аргументов .Таким образом, хотя Scala знает типы первых двух аргументов ... эта информация не передается в нашу анонимную функцию.

...

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

3 голосов
/ 02 сентября 2011

В некоторых случаях это различие имеет значение:

  1. Несколько списков параметров позволяют вам иметь такие вещи, как TwoParamClauses (2);это автоматически генерируемая функция типа Int => Int, которая добавляет 2 к своему аргументу.Конечно, вы можете определить то же самое самостоятельно, используя OneParamClause, но это займет больше нажатий клавиш

  2. Если у вас есть функция с неявными параметрами, которая также имеет явные параметры, неявные параметры должны бытьвсе в их собственном предложении параметров (это может показаться как произвольное ограничение, но на самом деле вполне разумно)

Кроме этого, я думаю, разница стилистическая.

...