2

I'm trying to implement a generic compose combinator

Recall that the composition of two functions—f and g-- is h(x) = f(g(x))

    def inc(x: Double) = x + 1
    def double(x: Double) = 2 * x

    def compose[T](f: T, g: T, x: Int) = f(g(x))

    println(compose(double, inc, 2))

I'm getting errors no matter what I try to do, I think I have a misunderstanding on generics or passing in functions...

What I want the compose function to do is take in two functions and execute f(g(x)) which would do g(x) first, then f(result of g(x)). In my example the result should be: 2(2+1) = 6

Question: How can I refactor my code to do this?

3
  • You need to specify that f and g are function types. T could be anything Commented Sep 29, 2017 at 19:40
  • Hm makes sense how do i specify that? Commented Sep 29, 2017 at 19:41
  • def inc[T <: Number](x: Int) = x + 1 def dbl[T <: Number](x: Int) = 2 * x Commented Sep 29, 2017 at 19:45

1 Answer 1

3

if you want to compose the functions, you have to make sure that the types match.

def compose[A,B,C](f: B => C, g: A => B, x: A): C = f(g(x))
println(compose(double, inc, 2.toDouble))

Then you can compose them. These combinators are already provided in Scala so you could do:

val inc = (v: Double) => v +1
val double = (v: Double) => v * 2
inc.andThen(double)
Sign up to request clarification or add additional context in comments.

4 Comments

Your solution works! But I think I do have a misunderstanding on generics. Why do we have to set C = f(g(x))? And the parameters B => C , A => B.. Is there a more simple way to refactor this or is it pretty simplified as is?
Oh that's not C = f(g(x)), you were defining the type of the function, right?
if you want to make the function completely generic to any input and output you need to make it generic for the input A, the intermediary state B and the result C, the type parameters in the function are making sure that the output of g is of the same type as the input of f, otherwise it would fail
> Is there a more simple way to refactor this or is it pretty simplified as is?I don't think so. B => C is just a syntactic sugar for f: Function1[B, C] so you can write it as "def compose[A,B,C](f: Function1[B, C], g: Function1[A, B], x: A): C = return f(g(x))" which is more verbose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.