II am trying to understand Scala collections by adding a new collection as follows:
class NewColl[V](values:Vector[V],someOtherParams)
extends IndexedSeq[V] with IndexedSeqLike[V, NewColl[V]] {
def fromSeq[V](seq: Seq[V]): NewColl[V] = ...
override def newBuilder[V]: Builder[V, NewColl[V]] =
new ArrayBuffer[V] mapResult fromSeq[V]
}
but I get the following error:
overriding method newBuilder in trait TraversableLike
of type => scala.collection.mutable.Builder[V,NewColl[V]];
method newBuilder in trait GenericTraversableTemplate
of type => scala.collection.mutable.Builder[V,IndexedSeq[V]] has incompatible type
Any Idea?
What I do in similar cases is to look at what the standard library does in similar cases. Looking at concrete subclasses of IndexedSeq they seem to mix in GenericTraversableTemplate. With that in mind, reworking your code to use it I get:
import collection.mutable._
import collection.generic.GenericTraversableTemplate
import collection.generic.GenericCompanion
class NewColl[V](values:Vector[V]) extends IndexedSeq[V] with
GenericTraversableTemplate[V, NewColl] {
def fromSeq[V](seq: Seq[V]): NewColl[V] = new NewColl(Vector(seq: _*))
override def companion: GenericCompanion[NewColl] = new GenericCompanion[NewColl]() {
def newBuilder[A]: Builder[A, NewColl[A]] = new Builder[A, NewColl[A]] {
val elems = new ArrayBuffer[A]()
def +=(a:A) = { elems += a; this }
def clear() { elems.clear }
def result(): NewColl[A] = fromSeq(elems)
}
}
}
(with someOtherParams removed for clarity)
Note that there are other questions on SO related to building classes on the scala 2.8 collection framework. For instance 5200505 which points to one of my favorite document The Architecture of Scala Collections. Also recently, Josh Suereth wrote a blog entry on creating your own collection class.
Related
I have an interesting Problem matching a Case Class in Scala....
I am using Akka and I have functionality that I will use in every Actor in my System, so created a Base Class for my Actor and I try to Match that Command there....
My Command looks like the following...
sealed trait ReportCommand extends ProcessCommand
final case class onReport(key: Key, replyTo: ActorRef[ResponseBase[State]]) extend ReportCommand
while I constructed Base Class so that it might be used from different Actors, onReport is delivered to Base Actor as generic parameter to be used in pattern match with a case class ...
abstract class BaseActor[E: ClassTag, R <: ReportBase[STATE], COMMAND](signal: TypeCase[R]) {
private val report = signal
def base[B <: E: ClassTag](cmd: E, state: STATE)(f: B => ReplyEffect[COMMAND, STATE]): ReplyEffect[COMMAND, STATE] =
cmd match {
case report(report) =>
Effect.reply(report.replytTo)(new ResponseBase[STATE]{
override def state: STATE = state
})
}
}
First if you think this construct will not work, it works, I have another Command (which I didn't place here) which does not have a generic parameter in the Command Class and above snippet is able to match that Snippet.
Now when I first try this code, Shapeless is complained about there is no mapping to ActorRef for Typeable of TypeCase, so after researching the internet I found I have to do the following....
implicit def mapActorRef[T: ClassTag]: Typeable[ActorRef[T]] =
new Typeable[ActorRef[T]] {
private val typT = Typeable[T]
override def cast(t: Any) : Option[ActorRef[T]] = {
if(t==null) None
else if(t.isInstanceOf[ActorRef[_]]) {
val o= t.asInstanceOf[ActorRef[_]]
for {
_ <- typT.cast(myClassOf)
} yield o.asInstanceOf[ActorRef[T]]
} else None
}
}
def myClassOf[T: ClassTag] = implicitly[ClassTag[T]].runtimeClass
implicit def responseBaseIsTypeable[S: Typeable] : Typeable[ResponseBase[S]] =
new Typeable[ResponseBase[S]] {
private val typS = Typeable[S]
override def cast(t: Any) : Option[ResponseState[S]] = {
if(t==null) None
else if(t.isIntanceOf[ResponseBase[_]]) {
val o = t.asInstanceOf[ResponseBase[_]]
for {
_ <- typS.cast(o.state)
} yield o.asInstanceOf[ResponseBase[S]]
} else None
}
}
Now after this changes I don't receive any Exceptions from Shapeless but case report(report) is not matching, I have no idea how we get a reasoning from Scala why it decide it does not match. During my debugging session I observed the following.
I am using the Akka's Ask Pattern to communicate with this actor...
val future : Future[BaseActor.ResponseBase[Actor.State]] = actorRef.ask[BaseActor.ResponseBase[Actor.State]](ref =>
Actor.onReport(key, ref)
)
now if I observe the cmd object that BaseActor receives, I see that 'ask' Pattern of the Akka change ActorRef in the onReport Command class to an ActorRefAdapter, of course ActorRefAdapter is a subclass of an ActorRef but I am not sure what I defined in the implicit for mapping ActorRef to TypeCase can deal with that stuff but I can't figure a way to change implicit to be aware of the Subtypes....
Unfortunately ActorRefAdapter is private to package package akka.actor.typed.internal.adapter so I can't define an extra mapping for ActorRefAdapter.
So can anybody see why Scala is not matching over my Shapeless <-> TypeCase configuration and give me some tips...
Thx for answers...
Your instance Typeable[ActorRef[T]] is incorrect.
Why did you decide to substitute a ClassTag in typT.cast(myClassOf)? This can't be meaningful.
I guess you used something like "No default Typeable for parametrized type" using Shapeless 2.1.0-RC2
If your gole is to make case report(replyTo) matching then you can define
implicit def mapActorRef[T: Typeable]: Typeable[ActorRef[T]] =
new Typeable[ActorRef[T]] {
private val typT = Typeable[T]
override def cast(t: Any): Option[ActorRef[T]] = {
if (t == null) None
else util.Try(t.asInstanceOf[ActorRef[T]]).toOption
}
override def describe: String = s"ActorRef[${typT.describe}]"
}
The problem is that this instance is also bad. Now case report(replyTo) is matching too much.
val actorTestKit = ActorTestKit()
val replyToRef = actorTestKit.spawn(ReplyToActor(), "replyTo")
import BaseActor._ // importing implicits
import shapeless.syntax.typeable._
val future: Future[BaseActor.ResponseBase[Actor.State]] = replyToRef.cast[ActorRef[Int]].get.ask[BaseActor.ResponseBase[Actor.State]](ref =>
1
)(5.seconds, system.scheduler)
Await.result(future, 10.seconds) // ClassCastException
A legal instance of the type class Typeable can be defined not for every type.
Providing instances for (concrete instantiations of) polymorphic types (where well defined) is pretty much the whole point of Typeable, both here and in Haskell.
The key phrase in the above is "where well defined". It's well defined in the case of non-empty container-like things. It's clearly not well defined for function values.
https://github.com/milessabin/shapeless/issues/69
ResponseBase is a non-empty container-like thing. But ActorRef is like a function T => Unit, so there shouldn't be a Typeable for it
trait ActorRef[-T] extends ... {
def tell(msg: T): Unit
...
}
You should reconsider your approach.
I am trying to update my project from Scala 2.12 to Scala 2.13. I see that the Scala team has done a lot of changes on the collection side.
I have a SetBuffer that looks like this in Scala 2.12
object SetBuffer extends MutableSetFactory[SetBuffer] {
override def empty[Elem] = new SetBuffer[Elem](Set.empty)
def apply[Elem](initialSet: Iterable[Elem]): SetBuffer[Elem] =
new SetBuffer[Elem](initialSet.toSet)
override def newBuilder[Elem] = new SetBufferBuilder[Elem]()
class SetBufferBuilder[Elem] extends mutable.GrowingBuilder[Elem, SetBuffer[Elem]](SetBuffer.empty) {
override def result(): SetBuffer[Elem] =
new SetBuffer[Elem](elems.getDelta)
}
}
class SetBuffer[ElemType](initialSet: Set[ElemType])
extends mutable.HashSet[ElemType]
with mutable.SetLike[ElemType, SetBuffer[ElemType]]
with GenericSetTemplate[ElemType, SetBuffer] {
initialSet.map(+=)
override def companion: SetBuffer.type = SetBuffer
def getDeltaBuffer: SetBuffer[ElemType] = {
SetBuffer[ElemType]((this -- initialSet).toSeq:_*)
}
def getDelta: immutable.Set[ElemType] = {
val deltaElements = (this -- initialSet).toSeq
immutable.Set[ElemType](deltaElements: _*)
}
def ++(that: Iterable[ElemType]): SetBuffer[ElemType] =
SetBuffer(toIterable ++ that)
def append(that: Iterable[ElemType]): Unit = this ++= that
def ++=(that: Iterable[ElemType]): Unit = that.map(+=)
}
Scala 2.13 removed mutable.SetLike[ElemType, SetBuffer[ElemType]] and GenericSetTemplate[ElemType, SetBuffer] and made mutable.HashSet final. Is there a way to rewrite the code in the class SetBuffer[ElemType](initialSet: Set[ElemType]) so it will behave the same and have the same performances?
Two ideas come to my mind.
First - you can try to use https://www.scala-lang.org/api/current/scala/collection/mutable/LinkedHashSet.html that seems to not be final. I am not sure if it's possible and I didn't search for performance characteristics.
Second, you go for composition over inheritance. Wrap the instance of HashSet and delegate all calls to it. You would have to implement quite a few interfaces to achieve the same behaviour though.
I have the following classes in Scala:
class A {
def doSomething() = ???
def doOtherThing() = ???
}
class B {
val a: A
// need to enhance the class with both two functions doSomething() and doOtherThing() that delegates to A
// def doSomething() = a.toDomething()
// def doOtherThing() = a.doOtherThing()
}
I need a way to enhance at compile time class B with the same function signatures as A that simply delegate to A when invoked on B.
Is there a nice way to do this in Scala?
Thank you.
In Dotty (and in future Scala 3), it's now available simply as
class B {
val a: A
export a
}
Or export a.{doSomething, doOtherThing}.
For Scala 2, there is unfortunately no built-in solution. As Tim says, you can make one, but you need to decide how much effort you are willing to spend and what exactly to support.
You can avoid repeating the function signatures by making an alias for each function:
val doSomething = a.doSomething _
val doOtherthing = a.doOtherThing _
However these are now function values rather than methods, which may or may not be relevant depending on usage.
It might be possible to use a trait or a macro-based solution, but that depends on the details of why delegation is being used.
Implicit conversion could be used for delegation like so
object Hello extends App {
class A {
def doSomething() = "A.doSomething"
def doOtherThing() = "A.doOtherThing"
}
class B {
val a: A = new A
}
implicit def delegateToA(b: B): A = b.a
val b = new B
b.doSomething() // A.doSomething
}
There is this macro delegate-macro which might just be what you are looking for. Its objective is to automatically implement the delegate/proxy pattern, so in your example your class B must extend class A.
It is cross compiled against 2.11, 2.12, and 2.13. For 2.11 and 2.12 you have to use the macro paradise compile plugin to make it work. For 2.13, you need to use flag -Ymacro-annotations instead.
Use it like this:
trait Connection {
def method1(a: String): String
def method2(a: String): String
// 96 other abstract methods
def method100(a: String): String
}
#Delegate
class MyConnection(delegatee: Connection) extends Connection {
def method10(a: String): String = "Only method I want to implement manually"
}
// The source code above would be equivalent, after the macro expansion, to the code below
class MyConnection(delegatee: Connection) extends Connection {
def method1(a: String): String = delegatee.method1(a)
def method2(a: String): String = delegatee.method2(a)
def method10(a: String): String = "Only method I need to implement manually"
// 96 other methods that are proxied to the dependency delegatee
def method100(a: String): String = delegatee.method100(a)
}
It should work in most scenarios, including when type parameters and multiple argument lists are involved.
Disclaimer: I am the creator of the macro.
I am tinkling with Scala and would like to produce some generic code. I would like to have two classes, one "outer" class and one "inner" class. The outer class should be generic and accept any kind of inner class which follow a few constraints. Here is the kind of architecture I would want to have, in uncompilable code. Outer is a generic type, and Inner is an example of type that could be used in Outer, among others.
class Outer[InType](val in: InType) {
def update: Outer[InType] = new Outer[InType](in.update)
def export: String = in.export
}
object Outer {
def init[InType]: Outer[InType] = new Outer[InType](InType.empty)
}
class Inner(val n: Int) {
def update: Inner = new Inner(n + 1)
def export: String = n.toString
}
object Inner {
def empty: Inner = new Inner(0)
}
object Main {
def main(args: Array[String]): Unit = {
val outerIn: Outer[Inner] = Outer.empty[Inner]
println(outerIn.update.export) // expected to print 1
}
}
The important point is that, whatever InType is, in.update must return an "updated" InType object. I would also like the companion methods to be callable, like InType.empty. This way both Outer[InType] and InType are immutable types, and methods defined in companion objects are callable.
The previous code does not compile, as it is written like a C++ generic type (my background). What is the simplest way to correct this code according to the constraints I mentionned ? Am I completely wrong and should I use another approach ?
One approach I could think of would require us to use F-Bounded Polymorphism along with Type Classes.
First, we'd create a trait which requires an update method to be available:
trait AbstractInner[T <: AbstractInner[T]] {
def update: T
def export: String
}
Create a concrete implementation for Inner:
class Inner(val n: Int) extends AbstractInner[Inner] {
def update: Inner = new Inner(n + 1)
def export: String = n.toString
}
Require that Outer only take input types that extend AbstractInner[InType]:
class Outer[InType <: AbstractInner[InType]](val in: InType) {
def update: Outer[InType] = new Outer[InType](in.update)
}
We got the types working for creating an updated version of in and we need somehow to create a new instance with empty. The Typeclass Pattern is classic for that. We create a trait which builds an Inner type:
trait InnerBuilder[T <: AbstractInner[T]] {
def empty: T
}
We require Outer.empty to only take types which extend AbstractInner[InType] and have an implicit InnerBuilder[InType] in scope:
object Outer {
def empty[InType <: AbstractInner[InType] : InnerBuilder] =
new Outer(implicitly[InnerBuilder[InType]].empty)
}
And provide a concrete implementation for Inner:
object AbstractInnerImplicits {
implicit def innerBuilder: InnerBuilder[Inner] = new InnerBuilder[Inner] {
override def empty = new Inner(0)
}
}
Invoking inside main:
object Experiment {
import AbstractInnerImplicits._
def main(args: Array[String]): Unit = {
val outerIn: Outer[Inner] = Outer.empty[Inner]
println(outerIn.update.in.export)
}
}
Yields:
1
And there we have it. I know this may be a little overwhelming to grasp at first. Feel free to ask more questions as you read this.
I can think of 2 ways of doing it without referring to black magic:
with trait:
trait Updatable[T] { self: T =>
def update: T
}
class Outer[InType <: Updatable[InType]](val in: InType) {
def update = new Outer[InType](in.update)
}
class Inner(val n: Int) extends Updatable[Inner] {
def update = new Inner(n + 1)
}
first we use trait, to tell type system that update method is available, then we put restrains on the type to make sure that Updatable is used correctly (self: T => will make sure it is used as T extends Updatable[T] - as F-bounded type), then we also make sure that InType will implement it (InType <: Updatable[InType]).
with type class:
trait Updatable[F] {
def update(value: F): F
}
class Outer[InType](val in: InType)(implicit updatable: Updatable[InType]) {
def update: Outer[InType] = new Outer[InType](updatable.update(in))
}
class Inner(val n: Int) {
def update: Inner = new Inner(n + 1)
}
implicit val updatableInner = new Updatable[Inner] {
def update(value: Inner): Inner = value.update
}
First we define type class, then we are implicitly requiring its implementation for our type, and finally we are providing and using it. Putting whole theoretical stuff aside, the practical difference is that this interface is that you are not forcing InType to extend some Updatable[InType], but instead require presence of some Updatable[InType] implementation to be available in your scope - so you can provide the functionality not by modifying InType, but by providing some additional class which would fulfill your constrains or InType.
As such type classes are much more extensible, you just need to provide implicit for each supported type.
Among other methods available to you are e.g. reflection (however that might kind of break type safety and your abilities to refactor).
I'm trying to create a data structure that has a PriorityQueue in it. I've succeeded in making a non-generic version of it. I can tell it works because it solves the A.I. problem I have.
Here is a snippet of it:
class ProntoPriorityQueue { //TODO make generic
implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] {
def compare(other: Node) = node.compare(other)
}
val hashSet = new HashSet[Node]
val priorityQueue = new PriorityQueue[Node]()
...
I'm trying to make it generic, but if I use this version it stops solving the problem:
class PQ[T <% Ordered[T]] {
//[T]()(implicit val ord: T => Ordered[T]) {
//[T]()(implicit val ord: Ordering[T] {
val hashSet = new HashSet[T]
val priorityQueue = new PriorityQueue[T]
...
I've also tried what's commented out instead of using [T <% Ordered[T]]
Here is the code that calls PQ:
//the following def is commented out while using ProntoPriorityQueue
implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] {
def compare(other: Node) = node.compare(other)
} //I've also tried making this return an Ordering[Node]
val frontier = new PQ[Node] //new ProntoPriorityQueue
//have also tried (not together):
val frontier = new PQ[Node]()(orderedNode)
I've also tried moving the implicit def into the Node object (and importing it), but essentially the same problem.
What am I doing wrong in the generic version? Where should I put the implicit?
Solution
The problem was not with my implicit definition. The problem was the implicit ordering was being picked up by a Set that was automatically generating in a for(...) yield(...) statement. This caused a problem where the yielded set only contained one state.
What's wrong with simply defining an Ordering on your Node (Ordering[Node]) and using the already-generic Scala PriorityQueue?
As general rule, it's better to work with Ordering[T] than T <: Ordered[T] or T <% Ordered[T]. Conceptually, Ordered[T] is an intrinsic (inherited or implemented) property of the type itself. Notably, a type can have only one intrinsic ordering relationship defined this way. Ordering[T] is an external specification of the ordering relationship. There can any be any number of different Ordering[T].
Also, if you're not already aware, you should know that the difference between T <: U and T <% U is that while the former includes only nominal subtype relations (actual inheritance), the latter also includes the application of implicit conversions that yield a value conforming to the type bound.
So if you want to use Node <% Ordered[Node] and you don't have a compare method defined in the class, an implicit conversion will be applied every time a comparison needs to be made. Additionally, if your type has its own compare, the implicit conversion will never be applied and you'll be stuck with that "built-in" ordering.
Addendum
I'll give a few examples based on a class, call it CIString that simply encapsulates a String and implements ordering as case-invariant.
/* Here's how it would be with direct implementation of `Ordered` */
class CIString1(val s: String)
extends Ordered[CIString1]
{
private val lowerS = s.toLowerCase
def compare(other: CIString1) = lowerS.compareTo(other.lowerS)
}
/* An uninteresting, empty ordered set of CIString1
(fails without the `extends` clause) */
val os1 = TreeSet[CIString1]()
/* Here's how it would look with ordering external to `CIString2`
using an implicit conversion to `Ordered` */
class CIString2(val s: String) {
val lowerS = s.toLowerCase
}
class CIString2O(ciS: CIString2)
extends Ordered[CIString2]
{
def compare(other: CIString2) = ciS.lowerS.compareTo(other.lowerS)
}
implicit def cis2ciso(ciS: CIString2) = new CIString2O(ciS)
/* An uninteresting, empty ordered set of CIString2
(fails without the implicit conversion) */
val os2 = TreeSet[CIString2]()
/* Here's how it would look with ordering external to `CIString3`
using an `Ordering` */
class CIString3(val s: String) {
val lowerS = s.toLowerCase
}
/* The implicit object could be replaced by
a class and an implicit val of that class */
implicit
object CIString3Ordering
extends Ordering[CIString3]
{
def compare(a: CIString3, b: CIString3): Int = a.lowerS.compareTo(b.lowerS)
}
/* An uninteresting, empty ordered set of CIString3
(fails without the implicit object) */
val os3 = TreeSet[CIString3]()
Well, one possible problem is that your Ordered[Node] is not a Node:
implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] {
def compare(other: Node) = node.compare(other)
}
I'd try with an Ordering[Node] instead, which you say you tried but there isn't much more information about. PQ would be declared as PQ[T : Ordering].