Type mismatch for functional composition

I 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 argue 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 get the following 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 so?

+4
source share
2 answers

This is because the compiler has difficulty outputting types correctly, in particular by invoking that A. You can help him by placing Aas the first argument and each function in a separate list of parameters:

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

And now it 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 explicitly specify a type parameter to help the compiler infer the correct type:

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

. .

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

, Nothing .

+5

Source: https://habr.com/ru/post/1658447/


All Articles