How to prevent stack overflow when using Scala's Predef.implicitly - scala

Given this simple code snippet I am astounded to provoke a stack overflow this easy:
implicit def foobar: Unit = implicitly[Unit]
In my little more complex use case I have the following situtation:
abstract class Foo {
type Repr_Tpe
protected implicit def repr2Ordered: Repr_Tpe => Ordered[Repr_Tpe]
}
class Bar extends Foo {
type Repr_Tpe = Long
protected implicit def repr2Ordered = implicitly[Repr_Tpe => Ordered[Repr_Tpe]]
}
Defining method repr2Ordered in class Foo does not work because type Repr_Tpe is abstract. So I decided to copy & paste the declaration and make a definition out of it; apparently leading to the stack overflow from above. Only by removing the modifier implicit from the definition in class Bar solves this problem.
Isn't there an elegant solution circumventing this pitfall?

You've defined foobar to be the implicit value of type Unit. Then you've defined it as the implicit value of type Unit. Thinking of it this way:
implicit def foobar: Unit = implicitly[Unit]
// you've defined foobar as the implicit value for Unit.
// so implicitly[Unit] is the same as calling foobar
// which is the same as:
implicit def foobar: Unit = foobar
You should be no more surprised that this causes a stack overflow than you would be by this statement:
def tharSheBlows: Unit = tharSheBlows
For something with a bit more elegance, I would use a view bound to ensure that the type paramater is Ordered instead.
scala> abstract class Foo[Repr_Tpe <% Ordered[Repr_Tpe]] {}
defined class Foo
scala> class Bar extends Foo[Long] {}
defined class Bar
scala> case class Unordered(data: String)
defined class Unordered
scala> class Bam extends Foo[Unordered] {}
<console>:10: error: No implicit view available from Unordered => Ordered[Unordered].
class Bam extends Foo[Unordered] {}
^
scala> implicit def bringOrder(u: Unordered) = new Ordered[Unordered] { def compare(that: Unordered) = u.data.compareTo(that.data) }
bringOrder: (u: Unordered)java.lang.Object with Ordered[Unordered]
scala> class Bam extends Foo[Unordered] {}
defined class Bam

Related

Cannot call use class name directly to map type after adding a companion project

When we have a case class, we call map the type with the name of the type, e.g.:
case class Foo(value: String)
val value = Some("Yay!")
val foo = value.map(Foo)
But if we also provide a companion object, this stops working value.map(Foo) and looks like this works: value.map(Foo(_)). Why?
case class Foo(value: String)
object Foo {}
val value = Some("Yay!")
val foo = value.map(Foo)
println(foo)
ScalaFiddle.scala:5: error: type mismatch;
found : ScalaFiddle.this.Foo.type
required: scala.this.Function1[lang.this.String,?]
val foo = value.map(Foo)
If you don't define object Foo at all, then the synthetic companion object has the following declaration:
<synthetic> object Foo
extends scala.runtime.AbstractFunction1[String,Foo]
with Serializable
But if you define your own object Foo as follows
case class Foo(v: String)
object Foo {}
then the declaration of the Foo object changes accordingly to:
object Foo extends scala.AnyRef with Serializable
and it no longer extends Function1.
The method apply(v: String): Foo is still automatically generated on Foo, but it no longer implements the Function1[String, Foo] interface. If you declare the companion object like this:
object Foo extends (String => Foo) { ... }
then you again can use it in expressions like value.map(Foo).
The value.map(Foo(_)) syntax always works, because it's just a shortcut for
value.map(x => Foo.apply(x))
and the closure doesn't care at all about what interfaces are implemented by Foo, it cares only about the existence of the apply method.

Scala: Working with Implicit Collisions

Suppose you have a class Foo and two additional implicit classes:
implicit class RichFoo1(val foo: Foo) extends AnyVal {
def doSomething: Bar
}
implicit class RichFoo2(val foo: Foo) extends AnyVal {
def doSomething: Baz
}
Now, if a class has imported both RichFoo1 and RichFoo2, it seems that there is a likelihood of a collision when doSomething() is called, and the compiler may complain due to the ordering between the imports of the two implicit classes and/or information about the relationship between Bar and Baz.
I'm considering a workaround in the manner of the following:
trait ConvertibleFromFoo[T] {
def doSomething[T]: T
}
implicit class RichFooAs(val foo: Foo) extends AnyVal {
def doSomething[T](implicit f: ConvertibleFromFoo[T]): T = f.doSomething
}
implicit val bar: ConvertibleFromBoo[Bar]
implicit val baz: ConvertibleFromBaz[Baz]
The idea would be that foo.doSomething[Bar] would (with a bit of code) do what RichFoo1(foo).doSomething would be doing, for example.
What would be the drawbacks with regards to this approach here, as opposed to, say, explicit ascription?
Related to this: when would it be appropriate to outright define an implicit conversion method over defining an implicit class? That is:
implicit def toBar(foo: Foo): Bar
versus
implicit class RichFoo(val foo: Foo) extends AnyVal {
def toBar: Bar
}
(For example: scala-java8-compat uses the latter for converting between Option and Optional)

Restrict Construction of Scala Class

Given:
class Foo(x: Int) {}
object Foo {
def apply(x: Int) = new Foo(x)
}
Besides marking Foo's constructor as private, how can I present a warning or compile-time failure when calling new Foo(...)?
In other words, I'd like to restrict (either by compile-time warning or error) construction of Foo to Foo.apply.
Is this possible?
In scala there are two idiomatic ways how to achieve that.
Constructor private to the class and companion object.
Factory has access to constructor, while anyone else doesn't:
class Foo private[Foo](val x: Int)
object Foo {
def apply(x:Int) = new Foo(x)
}
val foo = new Foo(1) // cannot compile
val foo1 = Foo(1) //compiles fine
Sealed abstract class.
In scala sealed class can be extended only in the same source file it is defined.
I suggest to make Foo sealed abstract class and return anonymous child of Foo in object's apply method.
sealed abstract class Foo(val x:Int)
object Foo {
def apply(x:Int):Foo = new Foo(x) {}
}
In this case Foo can be created nowhere except the file where it is defined.
UPD: Actually, this question was already discussed on stackoverflow.
UPD2: Added brief overview of both methods.

is there any way to use import someValue._ to implement overriding methods in scala?

Is there any way to do anything like this:
scala> trait Foo { def f:Int=0 }
defined trait Foo
scala> class FooImpl extends Foo { override val f = 1 }
defined class FooImpl
scala> class Bar(foo:Foo) extends Foo{ import foo._ }
defined class Bar
scala> (new Bar(new FooImpl)).f
res2: Int = 0
scala> trait Foo { def f:Int }
defined trait Foo
scala> class Bar(foo:Foo) extends Foo{ import foo._ }
<console>:8: error: class Bar needs to be abstract, since method f in trait Foo of type => Int is not defined
class Bar(foo:Foo) extends Foo{ import foo._ }
^
scala>
...in a way that would result in a subclass overriding a parent method via import? Basically I think it would be interesting to be able to use composition without all the typing. Just curious if anything like this is possible.
What you are really asking for is a way to delegate method implementations to a member.
That issue has already been addressed here: Proxies / delegates in Scala
Basically, there is a way to do it using macros. An implementation can be found here: https://github.com/adamw/scala-macro-aop
The above provides a #delegate macro annotation that can be applied to a data member to cause the compiler to generate code to delegate method calls to that member. Note that macro annotations are an experimental feature planned for Scala 2.11, but you can use them with Scala 2.10 using the Macro Paradise compiler plugin.
Self-typing can help here (depending on exactly how you will be working with these classes - this isn't composition of instances, more composition of types):
trait Foo { def f:Int }
trait FooImpl extends Foo { override val f = 1 } // Needs to be a trait to be mixed in.
class Bar {
this: Foo => // This requires that any Bar instance must mix in a Foo (must 'be' a Foo)
}
Then you can instantiate and use your Bar instance similar to the following:
scala> (new Bar with FooImpl).f
res1: Int = 1

scala - implementing trait method with parameter that is child of expected type

I'm very new to Scala so forgive me if this is a real easy question but I could not find anything to help me or I could not figure out the right search terms. How can I make this work?
scala> trait Foo
defined trait Foo
scala> class FooImpl extends Foo
defined class FooImpl
scala> trait Bar { def someMethod(foo: Foo) }
defined trait Bar
scala> class BarImpl extends Bar { def someMethod(foo: FooImpl) {} }
<console>:10: error: class BarImpl needs to be abstract, since method someMethod in trait Bar of type (foo: Foo)Unit is not defined
(Note that Foo does not match FooImpl)
class BarImpl extends Bar { def someMethod(foo: FooImpl) {} }
Why doesn't FooImpl match Foo since Foo is a trait? I'm guessing I need to alter the signature of someMethod in Bar to say that I'm expecting something that extends Foo or "with Foo" but I can't seem to find documentation for this.
The problem is that the Bar trait's someMethod declaration specifies that any kind of Foo can be passed as an argument. You can think of this as its "contract". The contract says that any implementation of Bar will have a method someMethod that will accept any kind of Foo.
Your BarImpl class is an implementation of Bar and has a someMethod implementation. Unfortunately, its implementation of someMethod only accepts FooImpl kinds of Foo objects: not any kind of Foo. Since it doesn't allow you to pass in Foo objects that aren't FooImpl objects, it violates the contract specified by the trait definition. Implementations can't be more restrictive than the contract specifies.
As an example:
class FooImplB extends Foo
val bar: Bar = new BarImpl
val foo: Foo = new FooImplB
bar.someMethod(foo)
Here we declare a Bar called bar and a Foo called foo. According to the definition of Foo I should be able to pass foo into bar.someMethod. Except that BarImpl.someMethod only accepts FooImpl kinds of Foos and not FooImplBs! So we have a problem.
dhg explained why this doesn't work and why you probably don't really want it.
But if you still want it, you can do it like this:
trait Foo
class FooImpl extends Foo
trait Bar[F <: Foo] { def someMethod(foo: F) }
class BarImpl extends Bar[FooImpl] {
def someMethod(foo: FooImpl) {}
}
Jens Schauder's answer works but forces you to define the type in the trait signature. Instead, you can do the same on the method level:
scala> trait Foo
defined trait Foo
scala> class FooImple extends Foo
defined class FooImple
scala> trait Bar { def methodA[T <: Foo](foo: T) }
defined trait Bar
scala> class BarImpl extends Bar { def methodA[FooImpl](foo: FooImpl){} }
defined class BarImpl