flatten is defined as:
override def flatten[B](implicit toIterableOnce: A => IterableOnce[B])
My code is:
val myList = List(1,2,3)
println(myList.map(x => List(x, 2*x)).flatten)
So if I understand it correctly, when I call flatten I need an implicit function defined somewhere and this function takes List[Int] as input and returns IterableOnce[Int].
I haven't defined any such function and code works fine, so implicit is found somewhere. How can I find where its exactly defined?
I was expecting it in Predef, but seems its not there.
If you do
// libraryDependencies += scalaOrganization.value % "scala-reflect" % scalaVersion.value
import scala.reflect.runtime.universe.reify
println(reify{ myList.map(x => List(x, 2*x)).flatten }.tree)
you'll see
App.this.myList.map(((x) => `package`.List.apply(x, 2.$times(x)))).flatten(Predef.$conforms)
so implicit toIterableOnce: A => IterableOnce[B] is Predef.$conforms (you were right, it's in Predef)
https://github.com/scala/scala/blob/2.13.x/src/library/scala/Predef.scala#L510
/** An implicit of type `A => A` is available for all `A` because it can always
* be implemented using the identity function. This also means that an
* implicit of type `A => B` is always available when `A <: B`, because
* `(A => A) <: (A => B)`.
*/
// $ to avoid accidental shadowing (e.g. scala/bug#7788)
implicit def $conforms[A]: A => A = <:<.refl
Indeed, List[Int] <: IterableOnce[Int]
implicitly[List[Int] <:< IterableOnce[Int]] // compiles
implicitly[List[Int] => IterableOnce[Int]] // compiles
It's useful to know how to debug implicits:
In scala 2 or 3, is it possible to debug implicit resolution process in runtime?
FWIW, if using Scala 2, you can also run your program with the -Xprint:typer flag using either scala or scalac, and you'll see all the implicits the compiler inserts in your program:
println(myList.map(x => List(x, 2*x)).flatten)
Gets translated into:
scala.Predef.println(Main.this.myList.map[List[Int]](((x: Int) =>
scala.`package`.List.apply[Int](x, 2.*(x))))
.flatten[Any](scala.Predef.$conforms[List[Int]]))
Related
2 different examples, the first one works:
import cats.syntax.either._
val e = 10.asRight[String]
def i2s(i:Int):String = i.toString
e.map(i => List(i2s(i))) //using explicit parameter
e.map(List(i2s(_))) //using no-name _ parameter
Now the same example with Option is not compiled:
e.map(Option(i2s(_)))
The error:
Error:(27, 15) type mismatch;
found : Option[Int => String]
required: Int => ?
e.map(Option(i2s(_)))
With explicit parameter it works fine:
e.map(i => Option(i2s(i)))
In both cases apply method is invoked with List and Option. List.apply signature:
def apply[A](xs: A*): List[A] = ???
Option.apply signature:
def apply[A](x: A): Option[A]
Please explain the difference.
Both of your List examples compile but they don't mean the same thing and don't produce the same results.
e.map(i => List(i2s(i))) //res0: scala.util.Either[String,List[String]] = Right(List(10))
e.map(List(i2s(_))) //java.lang.IndexOutOfBoundsException: 10
The 1st is easy to understand, so what's going on with the 2nd?
What's happening is that you're using eta expansion to create an Int => String function from the i2s() method. You then populate a List with that single function as the only element in the list, and then try to retrieve the value at index 10, which doesn't exist, thus the exception.
If you change the 1st line to val e = 0.asRight[String] then the exception goes away because something does exist at index 0, the function that was just put in there.
This compiles because a List instance will accept an Int as a parameter (via the hidden apply() method), but an Option instance does not have an apply() method that takes an Int (*) so that can't be compiled.
(*) The Option object does have an apply() method, but that's a different animal.
There are multiple things at play here as to why your first example with List[A] works. First, let's look at the expansion that happens on the expression:
val res: Either[String, Int => String] =
e.map[Int => String](List.apply[Int => String](((x$1: Int) => FlinkTest.this.i2s(x$1))));
Notice two things:
The expansion of the lambda expression happens inside List.apply, and perhaps not as you expected, for it to be outside of List.apply, like this:
e.map(i => List(i2s(i))
The return type from .map is somehow not Either[String, List[Int => String]], but Either[String, Int => String]. This is due to the fact that in it's hierarchy chain, List[A] extends PartialFunction[Int, A], thus allowing it to transform the result into a function type.
This doesn't work for Option[A], as it doesn't extend PartialFunction anywhere in it's type hierarchy.
The key takeaway here is that the expansion of the lambda expression doesn't work as you expect, as List(i2s(_)) expands to List(i2s(x => i2s(x)) and not List(i => i2s(i)). For more on underscore expansion, see What are all the uses of an underscore in Scala?
Why does this code produce an error
def test[A](a: List[A], f: A => A) = a.map(f)
println(test(List(1,2,3), _*2))
error: missing parameter type for expanded function ((x$2) => x$2.$times(2))
shouldn't Scala be able to tell that A is Int?
You need a second parameter list for this to work. I'm not sure how this is defined in the spec, however I have seen this before.
scala> def test[A](a: List[A])(f: A => A) = a.map(f)
test: [A](a: List[A])(f: (A) => A)List[A]
scala> test(List(1))(_+1)
res1: List[Int] = List(2)
This is the example, how to make it work in your case without changing anything.
scala> println(test(List(1,2,3), (i: Int) => i * 2 ))
Scala's type inference is limited, sometimes you should help!
Here is the article Making the most of Scala's (extremely limited) type inference
I have a function like so:
def ifSome[B, _](pairs:(Option[B], B => _)*) {
for((paramOption, setFunc) <- pairs)
for(someParam <- paramOption) setFunc(someParam)
}
and overloaded functions like these:
class Foo{
var b=""
def setB(b:String){this.b = b}
def setB(b:Int){this.b = b.toString}
}
val f = new Foo
then the following line produces an error:
ifSome(Option("hi") -> f.setB _)
<console>:11: error: ambiguous reference to overloaded definition,
both method setB in class Foo of type (b: Int)Unit
and method setB in class Foo of type (b: String)Unit
match expected type ?
ifSome(Option("hi") -> f.setB _)
But the compiler knows that we're looking for a Function1[java.lang.String, _], so why should the presence of a Function1[Int, _] present any confusion? Am I missing something or is this a compiler bug (or perhaps it should be a feature request)?
I was able to workaround this by using a type annotation like so
ifSome(Option("hi") -> (f.setB _:String=>Unit))
but I'd like to understand why this is necessary.
You'll want to try $ scalac -Ydebug -Yinfer-debug x.scala but first you'll want to minimize.
In this case, you'll see how in the curried version, B is solved in the first param list:
[infer method] solving for B in (bs: B*)(bfs: Function1[B, _]*)Nothing
based on (String)(bfs: Function1[B, _]*)Nothing (solved: B=String)
For the uncurried version, you'll see some strangeness around
[infer view] <empty> with pt=String => Int
as it tries to disambiguate the overload, which may lead you to the weird solution below.
The dummy implicit serves the sole purpose of resolving the overload so that inference can get on with it. The implicit itself is unused and remains unimplemented???
That's a pretty weird solution, but you know that overloading is evil, right? And you've got to fight evil with whatever tools are at your disposal.
Also see that your type annotation workaround is more laborious than just specifying the type param in the normal way.
object Test extends App {
def f[B](pairs: (B, B => _)*) = ???
def f2[B](bs: B*)(bfs: (B => _)*) = ???
def g(b: String) = ???
def g(b: Int) = ???
// explicitly
f[String](Pair("hi", g _))
// solves for B in first ps
f2("hi")(g _)
// using Pair instead of arrow means less debug output
//f(Pair("hi", g _))
locally {
// unused, but selects g(String) and solves B=String
import language.implicitConversions
implicit def cnv1(v: String): Int = ???
f(Pair("hi", g _))
}
// a more heavy-handed way to fix the type
class P[A](a: A, fnc: A => _)
class PS(a: String, fnc: String => _) extends P[String](a, fnc)
def p[A](ps: P[A]*) = ???
p(new PS("hi", g _))
}
Type inference in Scala only works from one parameter list to the next. Since your ifSome only has one parameter list, Scala won't infer anything. You can change ifSome as follows:
def ifSome[B, _](opts:Option[B]*)(funs: (B => _)*) {
val pairs = opts.zip(funs)
for((paramOption, setFunc) <- pairs)
for(someParam <- paramOption) setFunc(someParam)
}
leave Foo as it is...
class Foo{
var b=""
def setB(b:String){this.b = b}
def setB(b:Int){this.b = b.toString}
}
val f = new Foo
And change the call to ifSome accordingly:
ifSome(Option("hi"))(f.setB _)
And it all works. Now of course you have to check whether opts and funs have the same length at runtime.
I have a function which is able to know if an object is an instance of a Manifest's type. I would like to migrate it to a TypeTag version. The old function is the following one:
def myIsInstanceOf[T: Manifest](that: Any) =
implicitly[Manifest[T]].erasure.isInstance(that)
I have been experimenting with the TypeTags and now I have this TypeTag version:
// Involved definitions
def myInstanceToTpe[T: TypeTag](x: T) = typeOf[T]
def myIsInstanceOf[T: TypeTag, U: TypeTag](tag: TypeTag[T], that: U) =
myInstanceToTpe(that) stat_<:< tag.tpe
// Some invocation examples
class A
class B extends A
class C
myIsInstanceOf(typeTag[A], new A) /* true */
myIsInstanceOf(typeTag[A], new B) /* true */
myIsInstanceOf(typeTag[A], new C) /* false */
Is there any better way to achieve this task? Can the parameterized U be omitted, using an Any instead (just as it is done in the old function)?
If it suffices to use subtyping checks on erased types, do as Travis Brown suggested in the comment above:
def myIsInstanceOf[T: ClassTag](that: Any) =
classTag[T].runtimeClass.isInstance(that)
Otherwise you need to explicitly spell out the U type, so that scalac captures its type in a type tag:
def myIsInstanceOf[T: TypeTag, U: TypeTag] =
typeOf[U] <:< typeOf[T]
In your specific case, if you actually need to migrate existing code and keep the same behavior, you want ClassTag. Using TypeTag is more precise, but exactly because of that some code is going to behave differently, so (in general) you need to be careful.
If you indeed want TypeTag, we can do even better than the above syntax; the effect at the call site is the same as omitting U.
Recommended alternatives
Using pimping
With Eugene's answer, one has to spell both types, while it's desirable to deduce the type of that. Given a type parameter list, either all or none are specified; type currying could maybe help, but it seems simpler to just pimp the method. Let's use for this implicit classes, also new in 2.10, to define our solution in just 3 lines.
import scala.reflect.runtime.universe._
implicit class MyInstanceOf[U: TypeTag](that: U) {
def myIsInstanceOf[T: TypeTag] =
typeOf[U] <:< typeOf[T]
}
I would in fact argue that something like this, with a better name (say stat_isInstanceOf), could even belong into Predef.
Use examples:
//Support testing (copied from above)
class A
class B extends A
class C
//Examples
(new B).myIsInstanceOf[A] //true
(new B).myIsInstanceOf[C] //false
//Examples which could not work with erasure/isInstanceOf/classTag.
List(new B).myIsInstanceOf[List[A]] //true
List(new B).myIsInstanceOf[List[C]] //false
//Set is invariant:
Set(new B).myIsInstanceOf[Set[A]] //false
Set(new B).myIsInstanceOf[Set[B]] //true
//Function1[T, U] is contravariant in T:
((a: B) => 0).myIsInstanceOf[A => Int] //false
((a: A) => 0).myIsInstanceOf[A => Int] //true
((a: A) => 0).myIsInstanceOf[B => Int] //true
A more compatible syntax
If pimping is a problem because it changes the invocation syntax and you have existing code, we can try type currying (more tricky to use) as follows, so that just one type parameter has to be passed explicitly - as in your old definition with Any:
trait InstanceOfFun[T] {
def apply[U: TypeTag](that: U)(implicit t: TypeTag[T]): Boolean
}
def myIsInstanceOf[T] = new InstanceOfFun[T] {
def apply[U: TypeTag](that: U)(implicit t: TypeTag[T]) =
typeOf[U] <:< typeOf[T]
}
myIsInstanceOf[List[A]](List(new B)) //true
If you want to learn to write such code yourself, you might be interested in the discussion of variations shown below.
Other variations and failed attempts
The above definition can be made more compact with structural types:
scala> def myIsInstanceOf[T] = new { //[T: TypeTag] does not give the expected invocation syntax
def apply[U: TypeTag](that: U)(implicit t: TypeTag[T]) =
typeOf[U] <:< typeOf[T]
}
myIsInstanceOf: [T]=> Object{def apply[U](that: U)(implicit evidence$1: reflect.runtime.universe.TypeTag[U],implicit t: reflect.runtime.universe.TypeTag[T]): Boolean}
Using structural types is however not always a good idea, as -feature warns:
scala> myIsInstanceOf[List[A]](List(new B))
<console>:14: warning: reflective access of structural type member method apply should be enabled
by making the implicit value language.reflectiveCalls visible.
This can be achieved by adding the import clause 'import language.reflectiveCalls'
or by setting the compiler option -language:reflectiveCalls.
See the Scala docs for value scala.language.reflectiveCalls for a discussion
why the feature should be explicitly enabled.
myIsInstanceOf[List[A]](List(new B))
^
res3: Boolean = true
The problem is the slowdown due to reflection, required to implement structural types. Fixing it is easy, just makes the code a bit longer, as seen above.
A pitfall I had to avoid
In the above code, I write [T] instead of [T: TypeTag], my first attempt. It is interesting why it fails. To understand that, take a look:
scala> def myIsInstanceOf[T: TypeTag] = new {
| def apply[U: TypeTag](that: U) =
| typeOf[U] <:< typeOf[T]
| }
myIsInstanceOf: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])Object{def apply[U](that: U)(implicit evidence$2: reflect.runtime.universe.TypeTag[U]): Boolean}
If you look carefully at the type of the return value, you can see it's implicit TypeTag[T] => U => implicit TypeTag[U] (in pseudo-Scala notation). When you pass an argument, Scala will think it's for the first parameter list, the implicit one:
scala> myIsInstanceOf[List[A]](List(new B))
<console>:19: error: type mismatch;
found : List[B]
required: reflect.runtime.universe.TypeTag[List[A]]
myIsInstanceOf[List[A]](List(new B))
^
A tip
Last and least, one tip which might or not interest you: in this attempt, you are passing TypeTag[T] twice - hence you should remove : TypeTag after [T.
def myIsInstanceOf[T: TypeTag, U: TypeTag](tag: TypeTag[T], that: U) =
myInstanceToTpe(that) stat_<:< tag.tpe
I used the above suggestions to come up with the following. Feedback is welcomed.
/*
Attempting to cast Any to a Type of T, using TypeTag
http://stackoverflow.com/questions/11628379/how-to-know-if-an-object-is-an-instance-of-a-typetags-type
*/
protected def toOptInstance[T: ClassTag](any: Any) =
classTag[T].runtimeClass.isInstance(any) match {
case true =>
Try(any.asInstanceOf[T]).toOption
case false =>
/*
Allow only primitive casting
*/
if (classTag[T].runtimeClass.isPrimitive)
any match {
case u: Unit =>
castIfCaonical[T](u, "void")
case z: Boolean =>
castIfCaonical[T](z, "boolean")
case b: Byte =>
castIfCaonical[T](b, "byte")
case c: Char =>
castIfCaonical[T](c, "char")
case s: Short =>
castIfCaonical[T](s, "short")
case i: Int =>
castIfCaonical[T](i, "int")
case j: Long =>
castIfCaonical[T](j, "long")
case f: Float =>
castIfCaonical[T](f, "float")
case d: Double =>
castIfCaonical[T](d, "double")
case _ =>
None
}
else None
}
protected def castIfCaonical[T: ClassTag](value: AnyVal, canonicalName: String): Option[T] ={
val trueName = classTag[T].runtimeClass.getCanonicalName
if ( trueName == canonicalName)
Try(value.asInstanceOf[T]).toOption
else None
}
You can also capture type from TypeTag (into type alias), but only if it's not erased, so it will not work inside function:
How to capture T from TypeTag[T] or any other generic in scala?
I try to define the Reader monad with scalaz like this:
import scalaz._
import Scalaz._
final class Reader[E,A](private[Reader] val runReader: E => A)
object Reader {
def apply[E,A](f: E => A) = new Reader[E,A](f)
def env[E]: Reader[E,E] = Reader(identity _)
implicit def ReaderMonad[E] = new Monad[PartialApply1Of2[Reader,E]#Apply] {
def pure[A](a: => A) = Reader(_ => a)
def bind[A,B](m: Reader[E,A], k: A => Reader[E,B]) =
Reader(e => k(m.runReader(e)).runReader(e))
}
}
object Test {
import Reader._
class Env(val s: String)
def post(s: String): Reader[Env, Option[String]] =
env >>= (e => if (e.s == s) some(s).pure else none.pure)
}
but I get a compiler error:
reader.scala:27: reassignment to val
env >>= (e => if (e.s == s) some(s).pure else none.pure)
^
Why is that?
Thanks,
Levi
This error is fairly opaque, even by Scala's standards. Method names ending with = are treated specially -- they are first considered as a normal identifier, and failing that, they are expanded to a self assignment.
scala> def env[A] = 0
env: [A]Int
scala> env >>= 0
<console>:7: error: reassignment to val
env >>= 0
^
scala> env = env >> 0
<console>:6: error: reassignment to val
env = env >> 0
^
If you're confused about the syntactic interpretation of your program, it's a good idea to run scalac -Xprint:parser to see what's going on. Similarly, you can use -Xprint:typer or -Xprint:jvm to see later phases of the program transformation.
So, how do you call >>= on your Reader? First of all, you'll need to explicitly pass the type argument Env to env. The resulting Reader[Env, Env] must then be converted to a MA[M[_], A]. For simple type constructors, the implicit conversion MAs#ma will suffice. However the two param type constructor Reader must be partially applied -- this means it can't be inferred and instead you must provide a specific implicit conversion.
The situation would be vastly improved if Adriaan ever finds a spare afternoon to implement higher-order unification for type constructor inference. :)
Until then, here's your code. A few more comments are inline.
import scalaz._
import Scalaz._
final class Reader[E, A](private[Reader] val runReader: E => A)
object Reader {
def apply[E, A](f: E => A) = new Reader[E, A](f)
def env[E]: Reader[E, E] = Reader(identity _)
implicit def ReaderMonad[E]: Monad[PartialApply1Of2[Reader, E]#Apply] = new Monad[PartialApply1Of2[Reader, E]#Apply] {
def pure[A](a: => A) = Reader(_ => a)
def bind[A, B](m: Reader[E, A], k: A => Reader[E, B]) =
Reader(e => k(m.runReader(e)).runReader(e))
}
// No Higher Order Unification in Scala, so we need partially applied type constructors cannot be inferred.
// That's the main reason for defining function in Scalaz on MA, we can create one implicit conversion
// to extract the partially applied type constructor in the type parameter `M` of `MA[M[_], A]`.
//
// I'm in the habit of explicitly annotating the return types of implicit defs, it's not strictly necessary
// but there are a few corner cases it pays to avoid.
implicit def ReaderMA[E, A](r: Reader[E, A]): MA[PartialApply1Of2[Reader, E]#Apply, A] = ma[PartialApply1Of2[Reader, E]#Apply, A](r)
}
object Test {
import Reader._
class Env(val s: String)
def post(s: String): Reader[Env, Option[String]] =
// Need to pass the type arg `Env` explicitly here.
env[Env] >>= {e =>
// Intermediate value and type annotation not needed, just here for clarity.
val o: Option[String] = (e.s === s).guard[Option](s)
// Again, the partially applied type constructor can't be inferred, so we have to explicitly pass it.
o.pure[PartialApply1Of2[Reader, Env]#Apply]
}
}