I have a traits(below simple versions) and I want to mock Foo.
trait MyTrait[A]
trait Foo {
def bar[T: MyTrait](id:Int, data: T, other:Option[String] = None): String
}
I tried:
implicit val myTrait = new MyTrait[String] {}
val src = mock[Foo]
when(src.bar(any(),any(),any())).thenReturn("ok")
src.bar(1, "some", None)
It fails with:
Invalid use of argument matchers! 4 matchers expected, 3 recorded
How to mock this kind of method?
Mockito does not play well with scala code. What happens in your case is that
notify.bar(any(), any(), any()) has to be invoked inside when(), but type of the bar method is unknown, so when scalac is looking-up implicits there are possibly several instances of Writes that fit here (becuase all of them do).
You can do something like this to make it work:
when(src.bar[T](any(),any(),any())).thenReturn("ok")
Edit
Following your edit, i think you should reconsider usage of mockito in the first place. Here's what happens:
Foo has the following signature after desugaring
trait Foo {
def bar[T](id:Int, data: T, other:Option[String] = None)(implicit ev: MyTrait[T]): String
}
I don't know if you are aware how does mockito work, but here is a quick explanation why (from what i can tell) this error happens:
at runtime method bar has the following "signature" (due to type erasure):
bar(id: Int, data: Object, other: Option[Object], ev: MyTrait[Object])
when(src.bar[T](any(),any(),any())).thenReturn("ok") actually invokes this method on a proxy object and registers "matchers", but ev is passed myTrait instead of a matcher, so i guess this violates some constraints of the library
As side-note: usually mocking is not that hard and you can simply implement a "mocked" trait without any help from mockito or other similar library.
The syntax [T : MyTrait] is sugar to add (implicit typeClass: MyTrait[T]) as a second set of arguments, so basically you're missing an argument matcher as the error states
So if you do
val src = mock[Foo]
when(src.bar(any(),any(),any())(any())).thenReturn("ok")
it works as expected
BTW, this is a bit of self promotion but I just published a library called mockito-scala that improves the mockito syntax for Scala, is part of the mockito ecosystem so hopefully should become the default when working with Scala, you can find it here https://github.com/mockito/mockito-scala with the information to get the dependency and what problems does it actually solves.
Related
Here is a simple example:
trait Base {
type Out
def v: Out
}
object Base {
type Aux[T] = Base { type Out = T }
class ForH() extends Base {
type Out = HNil
override def v: Out = HNil
}
object ForH extends ForH
}
class TypeClass[B]
trait TypeClassLevel1 {
def summon[B](b: B)(implicit ev: TypeClass[B]): TypeClass[B] = ev
}
object TypeClass extends TypeClassLevel1 {
implicit def t1: TypeClass[Base.Aux[HNil]] = new TypeClass[Base.Aux[HNil]]
implicit def t2: TypeClass[Int] = new TypeClass[Int]
}
it("No Aux") {
val v = 2
TypeClass.summon(v) // works
}
it("Aux") {
val v = new Base.ForH()
TypeClass.summon(v) // oops
TypeClass.summon(Base.ForH) // oops
val v2 = new Base.ForH(): Base.Aux[HNil]
TypeClass.summon(v2) // works!
}
The object Base/ForH clearly has a stable path, this eliminate the possibility of the compiler not being able to resolve type ForH.Out.
What bothers me is not how incapable the compiler is to figure out the fact that ForH <:< Aux[HNil], but how easy it is to patch it up, just by a simple type upcast (last 2 lines). IMHO both features (type lambda & type classes) are important aspect of functional programming, why they can't work together at the same time?
If you are familiar with the compiler design I'll have an extra question: what does it take to improve the type class search algorithm to make it happen? Thanks a lot for your opinion.
UPDATE 1: a specific fix has been proposed but I have another problem trying to generalise it, please see In scala, how to make type class working for Aux pattern? - Part 2 for detail
So the compiler is able to infer ForH <:< Aux[HNil], but (tbh I don't know exactly why) when resolving an implicit when the return type uses a type lambda, it gets confused if you don't use a type bound.
Anyway that's probably not a great explanation, but at least I can make your code compile. Just change t1 to:
implicit def t1[T <: Base.Aux[HNil] ]: TypeClass[T] = new TypeClass[T]
this works for me in scastie using Scala 2.13.4.
What bothers me is not how incapable the compiler is to figure out the fact that ForH <:< Aux[HNil]
Surely the compiler does see that Base.ForH <:< Base.Aux[HNil]. You can check that
implicitly[Base.ForH <:< Base.Aux[HNil]]
compiles.
IMHO both features (type lambda & type classes) are important aspect of functional programming, why they can't work together at the same time?
Why are you talking about type lambdas? I can't see type lambdas in your question.
By the way, type lambdas is not a part of Scala 2 and ({ type λ[X] = ...F[X]... })#λ for a type lambda is more or less a hack. Actual type lambdas are added to Scala 3.
val v = new Base.ForH() has type Base.ForH (not Base.Aux[HNil] without upcasting via type ascription val v = new Base.ForH(): Base.Aux[HNil] or manual type specification val v: Base.Aux[HNil] = new Base.ForH()). TypeClass.summon(v) shouldn't compile since there is no implicit TypeClass[Base.ForH]. What implicit would you consider as a candidate? TypeClass.t1? But it's not a candidate, you can check that explicitly resolved
TypeClass.summon(v)(TypeClass.t1)
can't compile.
what does it take to improve the type class search algorithm to make it happen?
Implicit search algorithm shouldn't be improved in this specific place. It works properly, as intended.
You can make the type class contravariant
class TypeClass[-B]
Then TypeClass.t1 will be a candidate for TypeClass[Base.ForH] and TypeClass.summon(v) will compile.
In scala 2.13, how to use implicitly[value singleton type]?
Given:
case class Foo(x: BigDecimal)
I'd like to, at compile-time, build a List[Foo] where each Foo must have a BigDecimal value of 5.
So, I'd expect the following code to compile:
type Foo5Only = ???
val foos5: List[Foo5Only] = List(Foo(5), Foo(5))
But, I'd expect the following to fail to compile:
val bad: List[Foo5Only] = List(Foo(42))
I'm speculating that a shapeless Singleton type might be useful, but I don't actually understand it.
Note - I'm not interested, for this question, in an answer that results in using Either or Option.
As well as using shapeless' Nat type you could also use singleton types. Unfortunately Scala's built-in List type has covariance which gets in the way of type safety, but using a simple hand-crafted list type seems to work:
import shapeless.syntax.singleton._
sealed trait Lst[T]
case class Nil[T]() extends Lst[T]
case class Cons[T](head : T, tail : Lst[T]) extends Lst[T]
def list[T](t : T) : Lst[T] = {
Cons(t, Nil())
}
// OK
val foos5 = Cons(5.narrow, list(5.narrow))
// Compile-time type mismatch error.
val foos6 = Cons(42.narrow, list(5.narrow))
You might be able to elide the narrows with some macro-magic, but that's beyond my ability.
I have an interface defined using a structural type like this:
trait Foo {
def collection: {
def apply(a: Int) : String
def values() : collection.Iterable[String]
}
}
}
I wanted to have one of the implementers of this interface do so using a standard mutable HashMap:
class Bar {
val collection: HashMap[Int, String] = HashMap[Int, String]()
}
It compiles, but at runtime I get a NoSuchMethod exception when referring a Bar instance through a Foo typed variable. Dumping out the object's methods via reflection I see that the HashMap's apply method takes an Object due to type erasure, and there's some crazily renamed generated apply method that does take an int. Is there a way to make generics work with structural types? Note in this particular case I was able to solve my problem using an actual trait instead of a structural type and that is overall much cleaner.
Short answer is that the apply method parameter is causing you grief because it requires some implicit conversions of the parameter (Int => Integer). Implicits are resolved at compile time, the NoSuchMethodException is likely a result of these missing implicits.
Attempt to use the values method and it should work since there are no implicits being used.
I've attempted to find a way to make this example work but have had no success so far.
I am trying to test whether two "containers" use the same higher-kinded type. Look at the following code:
import scala.reflect.runtime.universe._
class Funct[A[_],B]
class Foo[A : TypeTag](x: A) {
def test[B[_]](implicit wt: WeakTypeTag[B[_]]) =
println(typeOf[A] <:< weakTypeOf[Funct[B,_]])
def print[B[_]](implicit wt: WeakTypeTag[B[_]]) = {
println(typeOf[A])
println(weakTypeOf[B[_]])
}
}
val x = new Foo(new Funct[Option,Int])
x.test[Option]
x.print[Option]
The output is:
false
Test.Funct[Option,Int]
scala.Option[_]
However, I expect the conformance test to succeed. What am I doing wrong? How can I test for higher-kinded types?
Clarification
In my case, the values I am testing (the x: A in the example) come in a List[c.Expr[Any]] in a Macro. So any solution relying on static resolution (as the one I have given), will not solve my problem.
It's the mixup between underscores used in type parameter definitions and elsewhere. The underscore in TypeTag[B[_]] means an existential type, hence you get a tag not for B, but for an existential wrapper over it, which is pretty much useless without manual postprocessing.
Consequently typeOf[Funct[B, _]] that needs a tag for raw B can't make use of the tag for the wrapper and gets upset. By getting upset I mean it refuses to splice the tag in scope and fails with a compilation error. If you use weakTypeOf instead, then that one will succeed, but it will generate stubs for everything it couldn't splice, making the result useless for subtyping checks.
Looks like in this case we really hit the limits of Scala in the sense that there's no way for us to refer to raw B in WeakTypeTag[B], because we don't have kind polymorphism in Scala. Hopefully something like DOT will save us from this inconvenience, but in the meanwhile you can use this workaround (it's not pretty, but I haven't been able to come up with a simpler approach).
import scala.reflect.runtime.universe._
object Test extends App {
class Foo[B[_], T]
// NOTE: ideally we'd be able to write this, but since it's not valid Scala
// we have to work around by using an existential type
// def test[B[_]](implicit tt: WeakTypeTag[B]) = weakTypeOf[Foo[B, _]]
def test[B[_]](implicit tt: WeakTypeTag[B[_]]) = {
val ExistentialType(_, TypeRef(pre, sym, _)) = tt.tpe
// attempt #1: just compose the type manually
// but what do we put there instead of question marks?!
// appliedType(typeOf[Foo], List(TypeRef(pre, sym, Nil), ???))
// attempt #2: reify a template and then manually replace the stubs
val template = typeOf[Foo[Hack, _]]
val result = template.substituteSymbols(List(typeOf[Hack[_]].typeSymbol), List(sym))
println(result)
}
test[Option]
}
// has to be top-level, otherwise the substituion magic won't work
class Hack[T]
An astute reader will notice that I used WeakTypeTag in the signature of foo, even though I should be able to use TypeTag. After all, we call foo on an Option which is a well-behaved type, in the sense that it doesn't involve unresolved type parameters or local classes that pose problems for TypeTags. Unfortunately, it's not that simple because of https://issues.scala-lang.org/browse/SI-7686, so we're forced to use a weak tag even though we shouldn't need to.
The following is an answer that works for the example I have given (and might help others), but does not apply to my (non-simplified) case.
Stealing from #pedrofurla's hint, and using type-classes:
trait ConfTest[A,B] {
def conform: Boolean
}
trait LowPrioConfTest {
implicit def ctF[A,B] = new ConfTest[A,B] { val conform = false }
}
object ConfTest extends LowPrioConfTest {
implicit def ctT[A,B](implicit ev: A <:< B) =
new ConfTest[A,B] { val conform = true }
}
And add this to Foo:
def imp[B[_]](implicit ct: ConfTest[A,Funct[B,_]]) =
println(ct.conform)
Now:
x.imp[Option] // --> true
x.imp[List] // --> false
I'm writing a Scala wrapper over some Java code with a method signature like method(cl: Class[_], name: String) and many getClass methods in code looks not good:
Creator.create(getClass, "One")
Creator.create(getClass, "Two")
Creator.create(getClass, "Three")
Creator.create(getClass, "Four")
So can we somehow get enclosing class implicitly like Creator.create("some name")?
Answer 1.
In general I warmly discourage reflection. However, if you really want to do it, in Scala 2.9.1 you can use Manifest
def create[T:Manifest](name:String) = {
val klass:Class[_] = t.erasure
}
In scala 2.10 you should have a look to TypeTag.
Answer 2.
However, as I already said, the right approach would not be to use class but implicit builders
trait Builder[T]{
def build(name:String):T
}
def create[T](name:String)(implicit builder:Builder[T]) = {
builder.build(name)
}
in that way you can limit what you can create by importing only the right implicits in scope, you won't rely on reflection and you won't risk to get horrible RuntimeExceptions
Post comment answer
If your point is to avoid calling getClass at each invocation, you can do the following
def create(name:String)(implicit klass:Class[_]) {
}
And you can call it this way
implicit val klass1 = myInstance.getClass
create("hello")
create("goodbye")