Как написать универсальный метод для автоматического разрешения типов при вызове? - PullRequest
1 голос
/ 12 ноября 2011

Допустим, у меня есть функция:

def foo[A,B](a : A, f : A => B) = ... 

И я называю это:

var x = new X()
foo(x, obj => ...

На данный момент ясно, что тип аргумента лямбда (здесь obj) это X (C # работает, например, так).

Однако в Scala я должен написать:

foo(x, (obj : X) => ...

Это вызывает много шума в коде.

Вопрос

Как написать мою функцию foo, чтобы избежать такой чрезмерной спецификации при каждом вызове? Или, может быть, я что-то упускаю, и добавление типа необходимо, потому что такой вызов (без информации о типе) будет неоднозначным.

Ответы [ 2 ]

6 голосов
/ 12 ноября 2011

Напишите функцию как

def foo[A,B](a: A)(f: A => B) = ...

вместо этого. Scala рассматривает каждый список параметров как набор ограничений, которые нужно решить, перемещаясь слева направо, и, возможно, слишком осторожен в отношении упрощающих предположений (например, тип A может быть суперклассом X в том виде, в котором вы его написали). Если вы используете отдельные списки параметров, это может нарушить обоснование. Кроме того, он разрешает использование, которое обычно синтаксически лучше:

foo(x) { y =>
  // Block of code dealing with y
}
1 голос
/ 13 ноября 2011

Я думаю, что карри в целом - это путь, но если у вас много функций с аргументами одного типа, вы можете сделать что-то вроде этого:

class Foo[T] {
  def apply[R](x: T, f: T => R) = f(x)
}

val foo = new Foo[Int]

foo(10, x => "Result: " + x.toString) // String = Result: 10
foo(10, x => x.toString * 5)          // String = 1010101010
foo(42, x => x + 100)                 // Int = 142
foo(12, x => Seq.iterate(x, 5)(_*2))  // Seq[Int] = List(12, 24, 48, 96, 192)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...