Определить функцию, которая переворачивает свои аргументы - PullRequest
1 голос
/ 01 июля 2019

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

var flipArguments = ((a: Any, b: Any) => Any ) => ((b: Any, a: Any) => Any)

но я получаю ошибку компиляции, которая выделяет вторую стрелку с сообщением

';' or newline expected

и я не понимаю, где я делаю синтаксическую ошибку.

Ответы [ 2 ]

5 голосов
/ 02 июля 2019

Это зависит от того, что вы подразумеваете под flip.

Отразить, как в «изменить значение двух переменных»

Если вы имеете в виду, что

var a = 1
var b = 2
flip(a, b)

должно привести кесли a равно 2, а b равно 1, что можно сделать со ссылками в C ++, то в Scala это невозможно.Вот объяснение .

Переверните как в «вернуть кортеж аргументов в обратном порядке»

Это уже отлично ответил в Пост Педро .Если это то, что вам нужно, вам, вероятно, следует использовать обобщенные значения, как упоминалось Луисом в комментариях.

Отразить, как в «перевернуть аргументы функций вокруг»

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

Вы можете написатьтакая функция, как это:

def flipAny(f: (Any, Any) => Any): (Any, Any) => Any =
  (a, b) => f(b, a)

, а затем вызвать ее для функции, подобной этой:

def stringify(a: Any, b: Any): String =
  s"a: ${a.toString}, b: ${b.toString}"

println(stringify(1,2))           // prints a: 1, b: 2
println(flipAny(stringify)(1,2))  // prints a: 2, b: 1

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

Что произойдет, если мы попытаемся использовать строковый результат stringify?

println(stringify(1,2).length)            // prints 10
//println(flipAny(stringify)(1,2).length) // doesn't compile

Вторая строка не компилируется, поскольку flipAny возвращает функцию, возвращающую Any,не String.

Вот еще одно определение, использующее дженерики:

def flip[A, B, C](f: (A, B) => C): (B, A) => C =
  (a, b) => f(b, a)

Это намного лучше.Мы получаем функцию от A и B до C и возвращаем функцию от B и A до C.Это сохраняет информацию о типе:

println(stringify(1,2))              // prints a: 1, b: 2
println(flip(stringify)(1,2))        // prints a: 2, b: 1
println(stringify(1,2).length)       // prints 10
println(flip(stringify)(1,2).length) // prints 10
1 голос
/ 01 июля 2019

Может быть, вы хотите что-то вроде этого:

def flipArguments(a:Any, b: Any): Any = (b, a)
...