1

I'm very new to scala so you may forgive me this basic newbie question. I have following code snippet.

type Pred[A, B] = (A, B) => Int;
def abs[A, B](p: (A, B) => Int): (A, B) => Int =
  (a, b) => if (p(a, b) < 0) -(p(a, b)) else (p(a, b));
def multiply(a: Int, b: Int): Int =
  a * b;
def subtract(a: Int, b: Int): Int =
  a - b;

val absMultiply = abs(multiply);
val absSubstract = abs(subtract);

println("abs(10 * 10) = " + absMultiply.apply(10, 10));
println("abs(10 - 100) = " + absSubstract.apply(10, 100));

So as I've understand it correctly it should be possible to replace (A,B) => Int with Pred[A, B].

def abs[A, B](p: Pred[A, B]): Pred[A, B] =
  (a, b) => if (p(a, b) < 0) -(p(a, b)) else (p(a, b));

But then I get an compiler exception

type mismatch;  found   : (Int, Int) => Int  required: (A, B) => Int    
type mismatch;  found   : (Int, Int) => Int  required: (A, B) => Int    

Have I misunderstood here something wrong?

Thank you very much for your help.

Cyrill

Cyrill Zadra
  • 182
  • 1
  • 15
  • What version are you using? With 2.9.2 I am not seeing any issue nor anything that seems syntactically incorrect. – Ryan O'Neill Mar 27 '13 at 01:41
  • 2
    FWIW, and irrespective of your question, the word "Predicate" usually refers to a Boolean valued function (usually of one argument), rather than in Integer valued one. You might consider something like "BinOp" rather than "Pred" as a name, if you don't want to confuse people. – Dave Griffith Mar 27 '13 at 01:47
  • @RyanO'Neill .. I'm using 2.10.0 – Cyrill Zadra Mar 27 '13 at 08:31
  • @Dave thank you for clarification.. so many terms I never heard of before ;-).. I'm slowly learning – Cyrill Zadra Mar 27 '13 at 08:35

1 Answers1

2

It works if you declare A and B as contravariant types:

type Pred[-A, -B] = (A, B) => Int

This is necessary because for multiply and subtract functions to be considered subtypes of Pred[A, B], their arguments must be supertypes of A and B. See this answer for an excellent explanation on the subject.

Community
  • 1
  • 1
Alex Yarmula
  • 10,477
  • 5
  • 33
  • 32