Suppose you work in a restaurant as a chef and one of your colleagues ask you a question: Implement a HOF (higher-order function) that performs currying. Looking for clues? Suppose you have the following two signatures for your HOF:
def curry[X,Y,Z](f:(X,Y) => Z) : X => Y => Z
Similarly, implement a function that performs uncurrying as follows:
def uncurry[X,Y,Z](f:X => Y => Z): (X,Y) => Z
Now, how could you use HOFs to perform the currying operation? Well, you could create a trait that encapsulates the signatures of two HOFs (that is, curry and uncurry) as follows:
trait Curry {
def curry[A, B, C](f: (A, B) => C): A => B => C
def uncurry[A, B, C](f: A => B => C): (A, B) => C
}
Now, you can implement and extend this trait as an object as follows:
object CurryImplement extends Curry {
def uncurry[X, Y, Z](f: X ...