Can I override a scala class method with a method from a trait? - scala

class PasswordCaseClass(val password:String)
trait PasswordTrait { self:PasswordCaseClass =>
override def password = "blue"
}
val o = new PasswordCaseClass("flowers") with PasswordTrait
Is it possible to override PasswordCaseClass's password with what is provided in PasswordTrait? Right now, I receive this error:
e.scala:6: error: overriding value password in class PasswordCase
Class of type String;
method password in trait PasswordTrait of type => java.lang.String needs to be a stable,
immutable value
val o = new PasswordCaseClass("flowers") with PasswordTrait
^
one error found
I would like to be able to have something like this:
class User(val password:String) {
}
trait EncryptedPassword { u:User =>
def password = SomeCriptographyLibrary.encrypt(u.password)
}
val u = new User("random_password") with EncryptedPassword
println(u.password) // see the encrypted version here

You can override a def with a val, but you can't do it the other way around. A val implies a guarantee -- that it's value is stable and immutable -- that a def does not.

This worked for me (with some modifications):
trait PasswordLike {
val password: String
}
class PasswordCaseClass(val password:String) extends PasswordLike
trait PasswordTrait extends PasswordLike {
override val password: String = "blue"
}
and then:
scala> val o = new PasswordCaseClass("flowers") with PasswordTrait
o: PasswordCaseClass with PasswordTrait = $anon$1#c2ccac
scala> o.password
res1: String = blue

You are trying to override the value with the method definition. It simply makes no sense - they have different semantics. Values supposed to be calculated once per object lifecycle (and stored within a final class attribute) and methods can be calculated multiple times. So what you are trying to do is to brake the contract of the class in a number of ways.
Anyway there is also compiler's fault - the error explanation is totally unclear.

Related

How to match a Case Class containing a Parameter with Generic Type

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.

what is the best practice of implementing a factory pattern/method in scala?

I wonder what is the best practice of implementing a factory pattern/method in scala?
say we have those kind of objects:
case class foo1(a:Int,b:String)
case class goo1(z:Double, w:String)
how to create them in generic way [by maybe using a trait etc...]?
thanks
If your goal is to write your own dependency injection module that provides instances on the fly, I'd strongly suggest that you lookup some of the existing tools. A simple google search for "Scala dependency injection frameworks" will yield many result such as MacWire, Guice,ReaderMonad,cake pattern and etc.
However my judgement aside from your motive and to simply answer the question here's one way you would do this in scala that also is type safe:
trait FactoryMethod[T] {
type Args
def defaultArgs: Args
def withArgs(args: Args): T
def default: T = withArgs(defaultArgs)
}
case class Foo(a:Int,b:String)
object Foo {
implicit object factory extends FactoryMethod[Foo] {
override type Args = (Int,String)
override def withArgs(args: Args): Foo = (Foo.apply _).tupled(args)
override def defaultArgs: Args = (1,"foo")
}
}
case class Goo(z:Double, w:String)
object Goo {
implicit object factory extends FactoryMethod[Goo] {
override type Args = (Double,String)
override def withArgs(args: Args): Goo = (Goo.apply _).tupled(args)
override def defaultArgs: Args = (2L,"goo")
}
}
object Factory {
def of[T](implicit factory: FactoryMethod[T]): factory.Args => T = factory.withArgs
def instanceOf[T](implicit factory: FactoryMethod[T]): T = factory.default
}
//obtain instance with default arguments
Factory.instanceOf[Goo]
//type safe way of obtaining instance with custom fed arguments
Factory.of[Foo].apply((-22,"baz"))
//By type safe I mean that the line below won't compile because the
//arguments fed for Foo are not compatible:
//Factory.of[Foo].apply(("bar","baz"))
//Note that if you abstract over the types Goo and Foo like this:
//def myMethod[T]: T = {
// Factory.instanceOf[T]
//}
//It won't compile unless you also ask for the needed implicit
//on the method signature
def myMethod[T: FactoryMethod]: T = {
Factory.instanceOf[T]
}

scala typing require implicit

I'm trying to build following
I have a parent generic class
abstract class ResultProvider[+T: Writes](db: DB) {
def get(id: Long): Future[Seq[T]]
}
And some implementations, e.g.
class LengthProvider(db: DB) extends ResultProvider[LengthResult](db){
override def get (userId: Long): Future[Seq[LengthResult]] = ...
}
object LengthProvider extends ((DB) => DisciplinePredictor) {
override def apply(db: DB) = new LengthProvider(db)
}
I have following configuration map:
val providers: Map[String, ((DB) => ResultProvider[???])] = Map(
"length" -> LengthProvider,
"width" -> WidthProvider,
...
)
My question is what should I put in place of ???. Ideally, it should be something like T : Writes, as I only care that this type has Writes implicit implemented, as I'm going to Json.toJson it. It will compile with Any, but then the information that the class should implement Writes implicit is lost.
Or should I use a different approach? I could probably create a superclass for all my result case classes (e.g.LengthResult), but I want to get away with the implicits.
You should be able to write ResultProvider[_] (search for "existential types" if you are unfamiliar with this syntax), but you'll need to give a name to the implicit:
abstract class ResultProvider[+T](db: DB)(implicit val writes: Writes[T]) { ... }
Elsewhere:
val provider: ResultProvider[_] = providers("length")
import provider.writes // makes the implicit visible here
...
You might need to help the compiler (or yourself, if you need to name the type) by providing a type variable:
providers("length") match {
case provider: ResultProvider[a] =>
import provider.writes
...
}

Scala - Add member variable to class from outside

Is it possible to add a member variable to a class from outside the class? (Or mimic this behavior?)
Here's an example of what I'm trying to do. I already use an implicit conversion to add additional functions to RDD, so I added a variable to ExtendedRDDFunctions. I'm guessing this doesn't work because the variable is lost after the conversion in a rdd.setMember(string) call.
Is there any way to get this kind of functionality? Is this the wrong approach?
implicit def toExtendedRDDFunctions(rdd: RDD[Map[String, String]]): ExtendedRDDFunctions = {
new ExtendedRDDFunctions(rdd)
}
class ExtendedRDDFunctions(rdd: RDD[Map[String, String]]) extends Logging with Serializable {
var member: Option[String] = None
def getMember(): String = {
if (member.isDefined) {
return member.get
} else {
return ""
}
}
def setMember(field: String): Unit = {
member = Some(field)
}
def queryForResult(query: String): String = {
// Uses member here
}
}
EDIT:
I am using these functions as follows: I first call rdd.setMember("state"), then rdd.queryForResult(expression).
Because the implicit conversion is applied each time you invoke a method defined in ExtendedRDDFunctions, there is a new instance of ExtendedRDDFunctions created for every call to setMember and queryForResult. Those instances do not share any member variables.
You have basically two options:
Maintain a Map[RDD, String] in ExtendedRDDFunctions's companion object which you use to assign the member value to an RDD in setMember. This is the evil option as you introduce global state and open pitfalls for a whole range of errors.
Create a wrapper class that contains your member value and is returned by the setMember method:
case class RDDWithMember(rdd: RDD[Map[String, String]], member: String) extends RDD[Map[String, String]] {
def queryForResult(query: String): String = {
// Uses member here
}
// methods of the RDD interface, just delegate to rdd
}
implicit class ExtendedRDDFunctions(rdd: RDD[Map[String, String]]) {
def setMember(field: String): RDDWithMember = {
RDDWithMember(rdd, field)
}
}
Beside the omitted global state, this approach is also more type safe because you cannot call queryForResult on instances that do not have a member. The only downsides are that you have to delegate all members of RDD and that queryForResult is not defined on RDD itself.
The first issue can probably be addressed with some macro magic (search for "delegate" or "proxy" and "macro").
The later issue can be resolved by defining an additional extension method in ExtendedRDDFunctions that checks if the RDD is a RDDWithMember:
implicit class ExtendedRDDFunctions(rdd: RDD[Map[String, String]]) {
def setMember(field: String): RDDWithMember = // ...
def queryForResult(query: String): Option[String] = rdd match {
case wm: RDDWithMember => Some(wm.queryForResult(query))
case _ => None
}
}
import ExtendedRDDFunctions._
will import all attributes and functions from Companion object to be used in the body of your class.
For your usage look for delagate pattern.

What class is this Builder pattern extending?

I found an interesting scala implementation of Builder pattern, but I can't understand what a few lines mean:
case class Built(a:Int, b:String){}
trait Status
trait Done extends Status
trait Need extends Status
class Builder[A<:Status,B<:Status] private(){
private var built = Built(0,"")
def setA(a0:Int)={
built = built.copy(a=a0)
this.asInstanceOf[Builder[Done,B]]
}
def setB(b0: String) = {
built = built.copy(b = b0)
this.asInstanceOf[Builder[A,Done]]
}
def result(implicit ev: Builder[A,B] <:< Builder[Done,Done]) = built
}
object Builder{
def apply() = new Builder[Need,Need]
}
1) What does private() mean in class Builder[A<:Status,B<:Status] private() class declaration?
2) What is the meaning of implicit ev: Builder[A,B] <:< Builder[Done,Done] in result function?
1)
The private means that the primary constructor for Builder can not be accessed from outside.
Since there are no other constructors, the only way to get an instance is through the companion object with the apply method.
Example:
val builder = Builder()
2)
You have methods in Builder to set both parameters for the Built case-class.
The method result gives you the constructed Built-instance. The evidence makes sure that you have set both parameters and will not allow you to create an instance if you didn't do it.
Example (I did not test this, so please correct me if I am wrong):
val builderA = Builder().setA(3)
val resultA = builderA.result //should not compile because this is Builder[Done, Need]
val builderAB = builderA.setB("hello") //now this is Builder[Done, Done]
val resultAB = builderAB.result //should compile and yield Built(3, "hello")
For your first question, the keyword private in this position means the constructor for the class is private.