2016-12-29 21 views
5

Chciałbym przyjechać do składni jako produktywne jak Haskell na desort = (reverse . sort) w Scala ... Oto moja próba:Nicea składnia złożenie funkcji w 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 

Czy istnieje jakiś sposób możemy pozbyć się _ w deklaracji Gf?

Odpowiedz

9

Dla funkcji tak, ale dla metod nie. Twoim problemem jest to, że próbujesz użyć metody dla g, a nie funkcji. Dla funkcji, nie jest już metoda ta nazywa 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 

Własne niejawna klasa będzie działać, jak również (choć nie wyglądał na dokładnych semantyki jest pragnienie), przy użyciu funkcji takich jak f i g, tak jak je zdefiniowałem. Będzie działać nawet dla funkcji i metody (w tej kolejności).

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

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

Jednak a andThen b nie działa jak jest, bo a to metoda, której nie można nazwać andThen dalej. Aby użyć andThen, należy przekonwertować na funkcję, która nie nastąpi automatycznie, ponieważ nie jest wymagana funkcja a _ andThen b eta-rozwija się a do funkcji, w której znajduje się metoda o nazwie andThen, i można podać argument o b (metoda), ponieważ kompilator niejawnie przekształci b w funkcję, ponieważ funkcja jest jedyną rzeczą, która jest oczekiwany jako argument z andThen. Function nie jest jedynym typem o nazwie andThen, więc kompilator nie może oczekiwać 100% czasu na przekształcenie metody w funkcję dla a.