bsky
bsky

Reputation: 20222

Type mismatch for function composition

I have defined an identity function and a composition function:

def identity[T](x: T): T = x
def composition[A, B, C](f: A => B, g: B => C)(x: A) = g(f(x))

I am trying to assert that the identity function can be applied on both sides with the same result:

assert(composition((x: Int) => x + 1, identity)(3) == composition(identity, (x: Int) => x + 1)(3))

However, I am getting these errors:

Error:(7, 40) type mismatch;
 found   : Nothing => Nothing
 required: Int => Nothing
assert(composition((x: Int) => x + 1, identity)(3) == composition(identity, (x: Int) => x + 1)(3));}

And:

Error:(7, 68) type mismatch;
 found   : Nothing => Nothing
 required: A => Nothing
assert(composition((x: Int) => x + 1, identity)(3) == composition(identity, (x: Int) => x + 1)(3));}

Why is this the case?

Upvotes: 4

Views: 159

Answers (2)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

This is the case because the compiler is having difficulty inferring the types properly, specifically inferring what A is. You can help him by placing A as the first argument and each function in a separate parameter list:

def composition[A, B, C](x: A)(f: A => B)(g: B => C) = g(f(x))

And now this works as expected:

scala> :pa
// Entering paste mode (ctrl-D to finish)

def identity[T](x: T): T = x
def composition[A, B, C](x: A)(f: A => B)(g: B => C) = g(f(x))

// Exiting paste mode, now interpreting.

identity: [T](x: T)T
composition: [A, B, C](x: A)(f: A => B)(g: B => C)C

scala> println(composition(3)((x: Int) => x + 1)(identity) == composition(3)(identity)((x: Int) => x + 1))
true

Alternatively, you can specify the type parameter explicitly to help the compiler infer the right type:

println(composition((x: Int) => x + 1, identity[Int], 3) == 
        composition(identity[Int], (x: Int) => x + 1, 3))

Upvotes: 8

Jegan
Jegan

Reputation: 1751

Below should work. Note the type param for the identity function.

assert(composition((x: Int) => x + 1, identity[Int])(3) == composition(identity[Int], (x: Int) => x + 1)(3))

Since you have not specified the type param for the identity function, it becomes Nothing and it does not match with the type signature of your method.

Upvotes: 5

Related Questions