Torhan Bartel
Torhan Bartel

Reputation: 560

Currying with 3 functions in Scala

Im trying to write a function using currying to compute a Collatz series... But im getting lost when trying to write the parameters for construct6(...)

def c: Int => Int = construct6(isEven)(dec, inc)

//DONT KNOW WHAT TO DO HERE
def construct6: ((Int => Boolean) => (Int => Int, Int => Int)) => (i => (e, o)) = { 
    if (i(n)) e(n) else o(n)
}

def isEven: (Int) => (Boolean) = (a) => (a % 2 == 0)
def dec: (Int) => (Int) = (a) => (a / 2)
def inc: (Int) => (Int) = (a) => (a * 3 + 1)

Upvotes: 0

Views: 112

Answers (2)

Paolo Falabella
Paolo Falabella

Reputation: 25844

Given:

def isEven: (Int) => (Boolean) = (a) => (a % 2 == 0)
def dec: (Int) => (Int) = (a) => (a / 2)
def inc: (Int) => (Int) = (a) => (a * 3 + 1)

you are still missing the n parameter to construct6 (as Andrew Cassidy says). Since you need to curry its parameters, it's more readable if you define construct6 like this (but it's basically the same definition you gave, I just added the n:Int at the end):

def construct6 (i:Int => Boolean)(e:(Int => Int)) (o:(Int => Int))(n:Int)
 = if (i(n)) e(n) else o(n)

you can now define c as a Int=>Int by leaving out the last parameter n to construct6. In the REPL:

scala> def c: Int => Int = construct6(isEven)(dec)(inc)
c: Int => Int

scala> c(8)
res0: Int = 4

which I believe is what you were trying to do.

If you want to infer c's type instead of specifying it as a Int => Int explicitly) you will have to use the omnipresent _ to confirm to Scala that you're not just leaving out anything by mistake:

scala> def c2= construct6(isEven)(dec)(inc) _
c2: Int => Int

scala> c2(8)
res1: Int = 4

Upvotes: 1

Andrew Cassidy
Andrew Cassidy

Reputation: 2998

You're construct6 function MUST take a Int n. Here is the function curried 3 times...

def construct6(i: Int => Boolean)(e: Int => Int, o: Int => Int)( n: Int): Int = 
    if (i(n)) e(n) else o(n)

When dealing with problems like this it is always important to look at the type signatures and see that they match up. Notice that construct6 MUST return an Int. We can doing some functional magic to make a function with a type signature to match Int => Int by doing this:

val c: Int => Int = construct6(isEven)(dec, inc)(_: Int)

We are partially applying the function you want for i, e, o, and leaving n as a variable.

Upvotes: 2

Related Questions