#scala
#scala
Вопрос:
Я не могу понять, почему этот код ломается. Оба метода отличаются входными параметрами.
object foo {
def x: String => String = x => x
def x: Option[String] => String = x => x.getOrElse("None")
}
Компилятор говорит method x is defined twice; ...
Как я могу обойти это?
Я хотел бы сохранить лямбда-нотацию, чтобы упростить конвейерную обработку при использовании функции.
Комментарии:
1. После удаления типа оба в основном справедливы
Function[Object, Object]
. Лучшее решение IMHO — использовать разные имена.2. оба метода отличаются входными параметрами. — Нет, они этого не делают. Они имеют один и тот же входной параметр, который равен none . Они оба возвращают функцию, которая отличается сигнатурой, но оба
x
являются просто методами, которые не принимают параметров3. Можете ли вы привести пример того, что вы подразумеваете под «конвейерной обработкой проще»? Может быть другое решение этой проблемы.
4. @Tim: Ниже приведен вспомогательный метод конвейерной обработки, который я использую. Поэтому я могу написать, например
f |> g
, для цепочки двух вызовов функций. мне легче читать, по сравнению сg(f(...))
:implicit class Pipelining[A](val a: A) extends AnyVal { def |>[B](f: A => B): B = f(a) }
5. Полиморфизм применяется только к вызову метода, и ваш код не выполняет никакого вызова метода, он просто вызывает функции. У вас не может быть значения, которое является полиморфной функцией.
Ответ №1:
Ответ на этот конкретный вопрос станет понятнее, если вы добавите скобки к методам:
object foo {
def x(): String => String = x => x
def x(): Option[String] => String = x => x.getOrElse("None")
}
Это дает понять, что методы отличаются только типом возвращаемого значения, а полиморфизм (в Scala) зависит от того, что типы аргументов разные.
Более широкая проблема здесь заключается в том, что полиморфизм применяется только к вызову метода. Она разрешается во время компиляции, а не во время выполнения, поэтому у вас не может быть значения, являющегося полиморфной функцией.
Это нормально:
object foo {
def poly(i: Int): Int = i
def poly(s: String): String = s
}
val i = foo.poly(1)
val s = foo.poly("a")
val y: Int => Int = foo.poly
Это НЕ НОРМАЛЬНО, потому что для этого потребуется x
содержать полиморфный тип функции:
val x = foo.poly
(Также обратите внимание, что в последних двух строках компилятор выполняет расширение eta от метода к функции)