The toInt method in StringLike doesn't take any arguments, and can only parse in decimal. So to parse binary, hex etc we need to resort to Java's Integer#parseInt(String s, int radix).
In an attempt to remedy this state of affairs, I tried the following
implicit def strToToIntable(s: String) = new {
def toInt(n: Int) = Integer.parseInt(s, n)
}
However,
"101".toInt(2)
causes the REPL compiler to "crash spectacularly" and doesn't work in compiled code either.
Is there some restriction on overloading existing methods using the "enrich my library" pattern?
Without the implicit, running "101".toInt(2) causes REPL to tell me that Int does not take parameters. So I guess what is happening is that it's running "101".toInt, then trying to call apply(2) on that, which doesn't make sense. I'd suggest a subtle rename of your pimped toInt to avoid the problem.
edit
I just had some success of my own. I explicitly defined a pimped string class as
class StrToRadixInt(s:String) {
def toInt(radix: Int) = Integer.parseInt(s,radix)
}
implicit def strToToIntable(s:String) = new StrToRadixInt(s)
And REPL was happy:
scala> "101".toInt(2)
res4: Int = 5
The REPL shouldn't crash--that's a bug. But even so, overloading of names is somewhat discouraged and also not supported in some contexts. Just use a different name:
implicit def parseBase(s: String) = new { def base(b: Int) = Integer.parseInt(s,b) }
scala> "10110" base 2
res1: Int = 22
Related
(I am fairly new to Scala, hope this isn't a stupid question.)
From what I can see, declaring a parameter to a function implicit has two (related, but quite different) uses:
It makes explicitly passing a corresponding argument when calling the given function optional when the compiler can find a unique suitable value to pass (in the calling scope).
It makes the parameter itself a suitable value to pass to other functions with implicit parameters (when calling them from within the given function).
In code:
def someFunction(implicit someParameter: SomeClass) = { // Note `implicit`
...
// Note no argument supplied in following call;
// possible thanks to the combination of
// `implicit` in `someOtherFunction` (1) and
// `implicit` in line 1 above (2)
someOtherFunction
...
}
def someOtherFunction(implicit someOtherParameter: SomeClass) = {
...
}
implicit val someValue = new SomeClass(...)
// Note no argument supplied in following call;
// possible thanks to `implicit` (1)
someFunction
This seems somewhat strange, doesn't it? Removing implicit from line 1 would make both calls (to someFunction from some other place, and to someOtherFunction from within someFunction) not compile.
What is the rationale behind this? (Edit: I mean what is the official rationale, in case any can be found in some official Scala resource.)
And is there a way to achieve one without the other (that is to allow passing an argument to a function implicitly without allowing it to be used implicitly within that function when calling other functions, and/or to use a non-implicit parameter implicitly when calling other functions)? (Edit: I changed the question a bit. Also, to clarify, I mean whether there is a language construct to allow this - not achieving the effect by manual shadowing or similar.)
For the first question
What is the rationale behind this?
answers are likely to be opinion-based.
And is there a way to achieve one without the other?
Yes, though it's a bit trickier than I thought initially if you want to actually use the parameter:
def someFunction(implicit someParameter: SomeClass) = {
val _someParameter = someParameter // rename to make it accessible in the inner block
{
val someParameter = 0 // shadow someParameter by a non-implicit
someOtherFunction // doesn't compile
someOtherFunction(_someParameter) // passed explicitly
}
}
The rationale is simple:
What has been passed as explicit, stays explicit
What has been marked as implicit, stays implicit
I don't think that any other combination (e.g. implicit -> explicit, let alone explicit -> implicit) would be easier to understand. The basic idea was, I think, that one can establish some common implicit context, and then define whole bunch of methods that expect same implicit variables that describe the established context.
Here is how you can go from implicit to explicit and back:
Implicit -> implicit (default)
def foo(implicit x: Int): Unit = {
bar
}
def bar(implicit x: Int): Unit = {}
Explicit -> implicit:
def foo(x: Int): Unit = {
implicit val implicitX = x
bar
}
def bar(implicit x: Int): Unit = {}
Implicit -> explicit: I would just use Alexey Romanov's solution, but one could imagine that if we had the following method in Predef:
def shadowing[A](f: Unit => A): A = f(())
then we could write something like this:
def foo(implicit x: Int): Unit = {
val explicitX = x
shadowing { x =>
// bar // doesn't compile
bar(explicitX) // ok
}
}
def bar(implicit x: Int): Unit = {}
Essentially, it's the same as Alexey Romanov's solution: we introduce a dummy variable that shadows the implicit argument, and then write the body of the method in the scope where only the dummy variable is visible. The only difference is that a ()-value is passed inside the shadowing implementation, so we don't have to assign a 0 explicitly. It doesn't make the code much shorter, but maybe it expresses the intent a little bit clearer.
I am trying to understand why exactly an implicit conversion is working in one case, but not in the other.
Here is an example:
case class Wrapper[T](wrapped: T)
trait Wrapping { implicit def wrapIt[T](x: Option[T]) = x.map(Wrapper(_))
class NotWorking extends Wrapping { def foo: Option[Wrapper[String]] = Some("foo") }
class Working extends Wrapping {
def foo: Option[Wrapper[String]] = {
val why = Some("foo")
why
}
}
Basically, I have an implicit conversion from Option[T] to Option[Wrapper[T]], and am trying to define a function, that returns an optional string, that gets implicitly wrapped.
The question is why, when I try to return Option[String] directly (NotWorking above), I get an error (found : String("foo") required: Wrapper[String]), that goes away if I assign the result to a val before returning it.
What gives?
I don't know if this is intended or would be considered a bug, but here is what I think is happening.
In def foo: Option[Wrapper[String]] = Some("foo") the compiler will set the expected type of the argument provided to Some( ) as Wrapper[String]. Then it sees that you provided a String which it is not what is expected, so it looks for an implicit conversion String => Wrapper[String], can't find one, and fails.
Why does it need that expected type stuff, and doesn't just type Some("foo") as Some[String] and afterwards try to find a conversion?
Because scalac wants to be able to typecheck the following code:
case class Invariant[T](t: T)
val a: Invariant[Any] = Invariant("s")
In order for this code to work, the compiler can't just type Invariant("s") as Invariant[String] because then compilation will fail as Invariant[String] is not a subtype of Invariant[Any]. The compiler needs to set the expected type of "s" to Any so that it can see that "s" is an instance of Any before it's too late.
In order for both this code and your code to work out correctly, I think the compiler would need some kind of backtracking logic which it doesn't seem to have, perhaps for good reasons.
The reason that your Working code does work, is that this kind of type inference does not span multiple lines. Analogously val a: Invariant[Any] = {val why = Invariant("s"); why} does not compile.
I'm defining some Scala implicits to make working with a particular unchangeable set of Java classes easier. The following Scala code is a simplified example that obviously looks crazy, in the real world I'm trying to grab particular resources (rather than numeric age) implicitly from the Monkey, Tree & Duck for use in various methods like purchaseCandles():
// actually 3 Java classes I can not change:
case class Monkey(bananas: Int)
case class Tree(rings: Int)
case class Duck(quacks: Seq[String])
// implicits I created to make my life easier...
implicit def monkey2Age(monkey: Monkey): Int = monkey.bananas / 1000
implicit def tree2Age(tree: Tree): Int = tree.rings
implicit def duck2Age(duck: Duck): Int = duck.quacks.size / 100000
// one of several helper methods that I would like to define only once,
// only useful if they can use an implicit parameter.
def purchaseCandles()(implicit age: Int) = {
println(s"I'm going to buy $age candles!")
}
// examples of usage
{
implicit val guest = Monkey(10000)
purchaseCandles()
}
{
implicit val guest = Tree(50)
purchaseCandles()
}
{
implicit val guest = Duck(Seq("quack", "quack", "quack"))
purchaseCandles()
}
The compiler error, which occurs 3 times:
could not find implicit value for parameter age: Int
purchaseCandles()
^
Leaving aside the many different ways in which this sample code is crazy, my real question is: can implicit conversions of implicit values satisfy implicit parameters in Scala?
Short answer: no. Scala's compiler will only ever look to apply a single implicit, so if it fails to spot an implicit int lying around, it will stop and give up.
However, you could write your purchaseCandles method to operate on types that can be converted to an Int, and require a parameter of that type:
def purchaseCandles[A <% Int]()(implicit age : A) = {
val asAge : Int = age
println(s"I'm going to buy $asAge candles!")
}
The asAge part is necessary to force the application of the implicit conversion.
As of yet, I seem to need to specify the type of A in this scenario, though I can't work out why: since there shouldn't be other values around of types that can be implicitly converted to Int (this happens with brand new types as well, so it's not the ubiquity of Int.) But you can do:
{
implicit val guest = Monkey(10000)
purchaseCandles[Monkey]()
}
This use of implicits, however, is probably a bad idea!
You actually can do that: You just have to mark the parameters of your implicit conversion as implicit as well:
implicit def monkey2Age(implicit monkey: Monkey): Int = monkey.bananas / 1000
implicit def tree2Age(implicit tree: Tree): Int = tree.rings
implicit def duck2Age(implicit duck: Duck): Int = duck.quacks.size / 100000
This will chain the implicits they way you want.
As always: Beware, it will also do so in places you don't want it to. By the way, I strongly advise against an implicit parameter of type Int (or an implicit value thereof). It is just too generic. (I'm somewhat assuming this is just like that in your example).
Why does this code throw an exception?
val x = new { def toInt(n: Int) = n*2 }
x.toInt(2)
scala.tools.nsc.symtab.Types$TypeError: too many arguments for method toInteger: (x$1: java.lang.Object)java.lang.Integer
at scala.tools.nsc.typechecker.Contexts$Context.error(Contexts.scala:298)
at scala.tools.nsc.typechecker.Infer$Inferencer.error(Infer.scala:207)
at scala.tools.nsc.typechecker.Infer$Inferencer.errorTree(Infer.scala:211)
at scala.tools.nsc.typechecker.Typers$Typer.tryNamesDefaults$1(Typers.scala:2350)
...
I'm using scala 2.9.1.final
Clearly a compiler bug (the compiler crashes, and REPL tells you That entry seems to have slain the compiler.). It's not signalling there's anything wrong with your code.
You're creating a single instance of type AnyRef{def toInt(n: Int): Int}, so creating a singleton object as Kyle suggests might be a better way of going about it. Or create a named class / trait that you insantiate, which works fine.
EDIT: As Luigi Plinge suggested, it's a compiler bug.
Maybe you want something like this...
object x {
def toInt(n:Int) = n * 2
}
scala> x.toInt(2)
res0: Int = 4
Is there any convenient way to dump all members of a specified object in Scala,
like var_dump(), PHP function?
As mentioned in "How to Dump/Inspect Object or Variable in Java" (yes, I know, the question is about Scala):
Scala (console) has a very useful feature to inspect or dump variables / object values :
scala> def b = Map("name" -> "Yudha", "age" -> 27)
b: scala.collection.immutable.Map[java.lang.String,Any]
scala> b
res1: scala.collection.immutable.Map[java.lang.String,Any] = Map((name,Yudha), (age,27))
But if you want more details, you can give REPL Scala Utils a try, in order to get a "Easier object inspection in the Scala REPL"
So I've written a utility for use on the Scala REPL that will print out all of the "attributes" of an object.
(Note: "I" being here: Erik Engbrecht, also on BitBucket)
Here's some sample usage:
scala> import replutils._
import replutils._
scala> case class Test(a: CharSequence, b: Int)
defined class Test
scala> val t = Test("hello", 1)
t: Test = Test(hello,1)
scala> printAttrValues(t)
hashCode: int = -229308731
b: int = 1
a: CharSequence (String) = hello
productArity: int = 2
getClass: Class = class line0$object$$iw$$iw$Test
That looks fairly anti-climatic, but after spending hours typing objName to see what's there, and poking at methods, it seems like a miracle.
Also, one neat feature of it is that if the class of the object returned is different from the class declared on the method, it prints both the declared class and the actual returned class.
You might want to look at ToStringBuilder in commons-lang, specificly ToStringBuilder.reflectionToString().
In compiled code, the nicest way is usually just to declare your type as a case class, then use the generated toString method.
Anything else subclassing Product should be just as easy (currently just tuples)
Failing that, write your own toString method, it's usually trivial enough...