2016-12-29 2 views
5

Я хотел бы, чтобы прийти к синтаксису, как продуктивный, как в Haskell desort = (reverse . sort) в Scala ... Вот моя попытка:Nice синтаксиса для композиции функции в Scala

implicit class Composition[A,B,C](val g: A => B) { 
    def o(f: B => C): A => C = { a:A => f(g(a))} 
} 

val fg = cos _ o sin 

Есть ли способ, мы можем избавиться от _ в декларации gf?

ответ

9

Для функций да, но для методов нет. Ваша проблема в том, что вы пытаетесь использовать метод для g, а не для функции. Для функций, уже есть способ это называется andThen:

val f: Int => Int = _ + 1 
val g: Int => String = _.toString 

scala> val fg = f andThen g 
fg: Int => String = <function1> 

scala> fg(2) 
res3: String = 3 

Ваш собственный неявный класс будет работать так же хорошо (хотя я не смотрел на точную семантике вы желаете), используя такие функции, как f и g, как я их определил. Он будет работать даже для функции и метода (в указанном порядке).

def a(i: Int): Int = i + 1 
def b(i: Int): String = i.toString 

scala> f andThen a 
res4: Int => Int = <function1> 

Однако a andThen b не работает, как есть, потому что a это метод, который вы не можете назвать andThen на. Чтобы использовать andThen, a необходимо преобразовать в функцию, которая не будет выполняться автоматически, потому что функция не обязательно ожидается. a _ andThen b eta-expands a в функцию, в которой есть метод, называемый andThen, и может быть предоставлен аргумент b (метод), поскольку компилятор будет неявно преобразовывать b в функцию, поскольку функция является единственной вещью, которая является ожидаемый как аргумент andThen. Function - не единственный тип с методом andThen, поэтому компилятор не может ожидать, что один 100% времени сделает преобразование из метода в a.

Смежные вопросы