Function.tupled и синтаксис заполнителя
Я видел этот пример использования Function.tupled в другом ответе: Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length)
,
Оно работает:
scala> Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length)
<console>:5: warning: method tupled in object Function is deprecated:
Use `f.tuple` instead
Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length)
^
res0: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3)
Кажется, я могу обойтись без, если я не хочу использовать синтаксис заполнителя.
scala> Map(1 -> "one", 2 -> "two") map (x => x._1 -> x._2.length)
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3)
Непосредственное использование синтаксиса заполнителя не работает:
scala> Map(1 -> "one", 2 -> "two") map (_._1 -> _._2.length)
<console>:5: error: wrong number of parameters; expected = 1
Map(1 -> "one", 2 -> "two") map (_._1 -> _._2.length)
Как работает Function.tupled? Кажется, в Function.tupled(_ -> _.length)
, Кроме того, как бы я использовал его, чтобы не получить предупреждение об устаревании?
1 ответ
ОБНОВЛЕНИЕ Амортизация была удалена сегодня, в ответ на эту проблему.
Корректировка функции - это просто адаптация FunctionN[A1, A2, ..., AN, R]
к Function1[(A1, A2, ..., AN), R]
Function.tuple
не рекомендуется в пользу FunctionN#tupled
, Следствием этого (возможно, непреднамеренного) является то, что средство определения типов не может вывести типы параметров в:
scala> Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled
<console>:5: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$minus$greater(x$2.length))
Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled
^
<console>:5: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$minus$greater(x$2.length))
Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled
Любой из них будет работать:
scala> Map(1 -> "one", 2 -> "two") map { case (a, b) => a -> b.length }
res8: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3)
scala> Map(1 -> "one", 2 -> "two") map ((_: Int) -> (_: String).length).tupled
res9: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3)
scala> Map(1 -> "one", 2 -> "two") map ((p: (Int, String)) => p._1 -> p._2.length)
res12: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3)
Я предлагаю вам прочитать ответы на этот недавний вопрос, чтобы глубже понять '_' в функциональных литералах и как работает вывод типов:
В Scala, в чем разница между использованием `_` и именованным идентификатором?
ОБНОВИТЬ
В ответ на комментарий, это так.
scala> val f = (x:Int, y:String) => x + ": " + y
f: (Int, String) => java.lang.String = <function2>
scala> f.tupled
res0: ((Int, String)) => java.lang.String = <function1>
scala> Map(1 -> "1") map f.tupled
res1: scala.collection.immutable.Iterable[java.lang.String] = List(1: 1)
Для этого требуется Scala 2.8. Обратите внимание, что Map#map может привести к другой карте, если тип возвращаемого значения функции Tuple2
иначе список, как указано выше.