0

If I have a Scala trait with two functions defined on it, one defined using just the signature def foo : Int => String and the other function declared with a paramter and a return type def bar(myInt : Int): String then I get different behavior for those methods.

import org.scalamock.scalatest.MockFactory
import org.scalatest.{Matchers, WordSpec}

class DefTest {

  trait DefTrait {
    def foo : Int => String
    def bar(myInt: Int) : String
  }

  class DefTest extends WordSpec with Matchers with MockFactory {
    val defStub = stub[DefTrait]

    defStub.bar _ when * returns "Works"
    defStub.foo _ when * return "nope"

  }
}

Signature only fail

IntellJ says there are Too many arguments for method when and expected: FunctionAdapter0[Boolean], actual: MatchAny.

SBT says:

type mismatch;
[error]  found   : org.scalamock.matchers.MatchAny
[error]  required: org.scalamock.function.FunctionAdapter0[Boolean]
[error]     defStub.foo _ when * returns "nope"
[error]                        ^

This makes me wonder:

  1. What is the difference between these two types of function declarations? I thought they were equivalent and I seem to have been able to use them interchangeably up until now.
  2. Is it possible to use the signature function definition foo: Int => String with the defStub.foo _ when 42 return "yay" syntax?
Matt Klein
  • 7,856
  • 6
  • 45
  • 46

1 Answers1

4

1. What is the difference between these two types of function declarations?

For def foo : Int => String it's returning a high-order function without accept parameters:

scala> :kind -v foo
scala.Function1's kind is F[-A1,+A2]
* -(-)-> * -(+)-> *
This is a type constructor: a 1st-order-kinded type.

and when you call foo(2), it's equal to foo.apply(2), apply method is used for function execution.

For def bar(myInt: Int) : String, it's a method, that accept a Int parameter.

2.Is it possible to use the signature function definition foo: Int => String with the defStub.foo _ when 42 return "yay" syntax?

for def foo : Int => String it's not accepting parameter, so you should use when() for this, and it's returning type is Int => String, so you should returns a high order function for this method. like:

defStub.foo _ when() returns((i: Int) => "nope")
chengpohi
  • 14,064
  • 1
  • 24
  • 42