Функциональная композиция методов, функций и частично применяемых функций в Scala
несколько похоже на вопрос переполнения стека Compose и andThen методы, я работал через Twitter Школа Scala учебник и быстро столкнулся с той же проблемой, что и комментатор (что было здорово, потому что я лег спать, думая, что моя проблема решена).
в учебнике, он определяет два метода как такового:
def addUmm(x: String) = x + " umm"
def addAhem(x: String) = x + " ahem"
и в то время как в более новых версиях Scala вы не можете вызвать compose на них как такие:addUmm(_).compose(addAhem(_))
, принятый ответ (и некоторые другие ответы, похоже, зависят от того, что addUmm
и addAhem
являются методами, а не функциями, что создает проблему при попытке вызова compose. Я лег спать довольный, успешно работать:
scala> ((s: String) => s + " umm").compose((s: String) => s + " ahem")
res0: String => java.lang.String = <function1>
прохладный. Проблема в том, что, не имея возможности создавать методы, имеет смысл, когда я то же самое со значениями, которые я знаю, оцениваю до Function1
:
val a = (s: String) => s + " umm"
val b = (s: String) => s + " ahem"
val c = a(_).compose(b(_))
хорошо, что откашливает то же ошибка, которую сделал исходный вопрос, хотя на этот раз они являются частичными приложениями функций, а не методами. Один из ответов в исходном вопросе (высокопоставленный, но не принятый ответ), похоже, намекает, что он имеет отношение к тому, как расширяется частичное приложение, каково объяснение?
для новичка Scala, тот факт, что inferencer получает a(_).compose(b(_))
неправильно, независимо от того, если вы явно указать _: String
в обоих местах, но a.compose(b)
несколько запутанным.
2 ответов
a(_).compose(b(_))
увеличивается до x => { a(x).compose(y => b(y) }
. Отсюда и ошибка. То, что вы хотите (x => a(x)).compose(y => b(y))
. Добавление пары скобок исправляет это.
scala> (a(_)).compose(b(_: String))
res56: String => java.lang.String = <function1>
scala> res56("hello")
res57: java.lang.String = helloahemumm
но поскольку a
и b
функции, вы можете избежать всего этого хлама и просто сделать a compose b
.
вы можете использовать просто "a compose b".
scala> val c = a compose b
c: String => java.lang.String = <function1>