In scala is it possible to declare a generic abstract function in a base class and then
provide different concrete implementations in various derived classes like this:
abstract class B {
def foo[T,V](u:T):V
}
class D extends B {
def foo(u:T_0) = {...}
def foo(u:T_1) = {...}
....
}
and likewise for classes D1, D2,... derived from B (with possibly different concrete types T_j)
accross classes D_j in order to use obj.foo(u) and the compiler flags whenever foo is used on an argument of a type for which foo is not defined.
In short the question is: is a class derived from B considered concrete as soon as foo is defined
for at least one concrete type T?
In your example, you can't specialize U and T within D, you have to match the parameters from the base class. You also can't provide individual special cases of an override within a subclass, like a partial function -- a concrete class must provide implementations for each abstract method, covering all parameters.
It seems to me like what you really want is type parameters at the class level, on B itself, so that derived classes specialize those parameters and then the interface of the foo method they inherit becomes specialized accordingly. So, you'd want to do something like:
abstract class B[T, V] {
def foo(u: T): V
}
class D extends B[String, Int] {
def foo(u: String): Int = u.length
}
(You may also find it useful to add variance annotations class B[-T, +V], but that's another story.)
Related
I'm trying to construct a trait and an abstract class to subtype by messages (In an Akka play environment) so I can easily convert them to Json.
What have done so far:
abstract class OutputMessage(val companion: OutputMessageCompanion[OutputMessage]) {
def toJson: JsValue = Json.toJson(this)(companion.fmt)
}
trait OutputMessageCompanion[OT] {
implicit val fmt: OFormat[OT]
}
Problem is, when I'm trying to implement the mentioned interfaces as follows:
case class NotifyTableChange(tableStatus: BizTable) extends OutputMessage(NotifyTableChange)
object NotifyTableChange extends OutputMessageCompanion[NotifyTableChange] {
override implicit val fmt: OFormat[NotifyTableChange] = Json.format[NotifyTableChange]
}
I get this error from Intellij:
Type mismatch, expected: OutputMessageCompanion[OutputMessage], actual: NotifyTableChange.type
I'm kinda new to Scala generics - so help with some explanations would be much appreciated.
P.S I'm open for any more generic solutions than the one mentioned.
The goal is, when getting any subtype of OutputMessage - to easily convert it to Json.
The compiler says that your companion is defined over the OutputMessage as the generic parameter rather than some specific subtype. To work this around you want to use a trick known as F-bound generic. Also I don't like the idea of storing that companion object as a val in each message (after all you don't want it serialized, do you?). Defining it as a def is IMHO much better trade-off. The code would go like this (companions stays the same):
abstract class OutputMessage[M <: OutputMessage[M]]() {
self: M => // required to match Json.toJson signature
protected def companion: OutputMessageCompanion[M]
def toJson: JsValue = Json.toJson(this)(companion.fmt)
}
case class NotifyTableChange(tableStatus: BizTable) extends OutputMessage[NotifyTableChange] {
override protected def companion: OutputMessageCompanion[NotifyTableChange] = NotifyTableChange
}
You may also see standard Scala collections for an implementation of the same approach.
But if all you need the companion for is to encode with JSON format, you can get rid of it like this:
abstract class OutputMessage[M <: OutputMessage[M]]() {
self: M => // required to match Json.toJson signature
implicit protected def fmt: OFormat[M]
def toJson: JsValue = Json.toJson(this)
}
case class NotifyTableChange(tableStatus: BizTable) extends OutputMessage[NotifyTableChange] {
override implicit protected def fmt: OFormat[NotifyTableChange] = Json.format[NotifyTableChange]
}
Obviously is you also want to decode from JSON you still need a companion object anyway.
Answers to the comments
Referring the companion through a def - means that is a "method", thus defined once for all the instances of the subtype (and doesn't gets serialized)?
Everything you declare with val gets a field stored in the object (instance of the class). By default serializers trying to serialize all the fields. Usually there is some way to say that some fields should be ignored (like some #IgnoreAnnotation). Also it means that you'll have one more pointer/reference in each object which uses memory for no good reason, this might or might not be an issue for you. Declaring it as def gets a method so you can have just one object stored in some "static" place like companion object or build it on demand every time.
I'm kinda new to Scala, and I've peeked up the habit to put the format inside the companion object, would you recommend/refer to some source, about how to decide where is best to put your methods?
Scala is an unusual language and there is no direct mapping the covers all the use cases of the object concept in other languages. As a first rule of thumb there are two main usages for object:
Something where you would use static in other languages, i.e. a container for static methods, constants and static variables (although variables are discouraged, especially static in Scala)
Implementation of the singleton pattern.
By f-bound generic - do you mean the lower bound of the M being OutputMessage[M] (btw why is it ok using M twice in the same expr. ?)
Unfortunately wiki provides only a basic description. The whole idea of the F-bounded polymorphism is to be able to access to the type of the sub-class in the type of a base class in some generic manner. Usually A <: B constraint means that A should be a subtype of B. Here with M <: OutputMessage[M], it means that M should be a sub-type of the OutputMessage[M] which can easily be satisfied only by declaring the child class (there are other non-easy ways to satisfy that) as:
class Child extends OutputMessage[Child}
Such trick allows you to use the M as a an argument or result type in methods.
I'm a bit puzzled about the self bit ...
Lastly the self bit is another trick that is necessary because F-bounded polymorphism was not enough in this particular case. Usually it is used with trait when traits are used as a mix-in. In such case you might want to restrict in what classes the trait can be mixed in. And at the same type it allows you to use the methods from that base type in your mixin trait.
I'd say that the particular usage in my answer is a bit unconventional but it has the same twofold effect:
When compiling OutputMessage the compiler can assume that the type will also somehow be of the type of M (whatever M is)
When compiling any sub-type compiler ensures that the constraint #1 is satisfied. For example it will not let you to do
case class SomeChild(i: Int) extends OutputMessage[SomeChild]
// this will fail because passing SomeChild breaks the restriction of self:M
case class AnotherChild(i: Int) extends OutputMessage[SomeChild]
Actually since I had to use self:M anyway, you probably can remove the F-bounded part here, living just
abstract class OutputMessage[M]() {
self: M =>
...
}
but I'd stay with it to better convey the meaning.
As SergGr already answered, you would need an F-Bounded kind of polymorphism to solve this as it is right now.
However, for these cases, I believe (note this is only my opinion) is better to use Typeclasses instead.
In your case, you only want to provide a toJson method to any value as long as they have an instance of the OFormat[T] class.
You can achieve that with this (more simple IMHO) piece of code.
object syntax {
object json {
implicit class JsonOps[T](val t: T) extends AnyVal {
def toJson(implicit: fmt: OFormat[T]): JsVal = Json.toJson(t)(fmt)
}
}
}
final case class NotifyTableChange(tableStatus: BizTable)
object NotifyTableChange {
implicit val fmt: OFormat[NotifyTableChange] = Json.format[NotifyTableChange]
}
import syntax.json._
val m = NotifyTableChange(tableStatus = ???)
val mJson = m.toJson // This works!
The JsonOps class is an Implicit Class which will provide the toJson method to any value for which there is an implicit OFormat instance in scope.
And since the companion object of the NotifyTableChange class defines such implicit, it is always in scope - more information about where does scala look for implicits in this link.
Additionally, given it is a Value Class, this extension method does not require any instantiation in runtime.
Here, you can find a more detailed discussion about F-Bounded vs Typeclasses.
I'm reading structured JSON, using Play Frameworks' JSON Reads to build up an object graph with case classes.
An example:
case class Foo (
id: Int,
bar_id: Int,
baz_id: Int,
x: Int,
y: String
)
{
var bar: Bar = null
var baz: Baz = null
}
After building the Foo, I must come back later and decorate it by setting bar and baz. Those are defined in other JSON files and only known when all parsing is complete. But this means Foo can't be immutable.
What is the "right" way in Scala to make an immutable object, and then a decorated version of it, without repeating every field of Foo multiple times, over and over?
I know several ways that feel wrong:
make "bar: Option[Bar]" and "baz: Option[Baz]" case class parameters, and then I can use "copy" to make new versions of the Foo class with them set to something; but then I have to check them every single time they're accessed - inefficient, unsafe, not able to make a DecoratedFoo that just is guaranteed to have the right structure
make a second case class that is a copy-paste of all the structure in the first, but adding the two extra decorated parameters - but this means echoing the entire parameter list in the definition, and again when creating instances of it
Case class inheritance is apparently controversial, and in any case also appears to require me to repeat every single parameter anyway, in the subclass constructor?
Make a non-case superclass listing the common case class parameters. Then extend it in the case class. But this would seem to still require repeating every single parameter in the subclass constructor as well.
I see blogs with people talking about this problem and using reflection at runtime to populate the base attributes of their decorated copies - this avoids echo but now you have no type safety, specifying attribute names as strings, overhead, etc...
Surely Scala must have a way to let people compose more complicated immutable objects out of simpler ones without having to copy each and every part of them by hand?
You could introduce a new trait for the processed types, a class that extends that trait, and an implicit conversion:
case class Foo(bar: Int)
trait HasBaz {
val baz: Int
}
class FooWithBaz(val foo: Foo, val baz: Int) extends HasBaz
object FooWithBaz {
implicit def innerFoo(fwb: FooWithBaz): Foo = fwb.foo
implicit class RichFoo(val foo: Foo) extends AnyVal {
def withBaz(baz: Int) = new FooWithBaz(foo, baz)
}
}
So then you can do:
import FooWithBaz._
Foo(1).withBaz(5)
And, although withBaz returns a FooWithBaz, we can treat the return value like a Foo when necessary, because of the implicit conversion.
Combining Option and type parameters you can flag your case class, and track whether the processed fields are empty, statically:
import scala.language.higherKinds
object Acme {
case class Foo[T[X] <: Option[X] forSome { type X }](a: Int,
b: String,
c: T[Boolean],
d: T[Double])
// Necessary, Foo[None] won't compile
type Unprocessed[_] = None.type
// Just an alias
type Processed[X] = Some[X]
}
Example use case:
import Acme._
val raw: Foo[Unprocessed] = Foo[Unprocessed](42, "b", None, None)
def process(unprocessed: Foo[Unprocessed]): Foo[Processed] =
unprocessed.copy[Processed](c = Some(true), d = Some(42d))
val processed: Foo[Processed] = process(raw)
// No need to pattern match, use directly the x from the Some case class
println(processed.c.x)
println(processed.d.x)
I used this once in my current project. The main problem I encountered is when I want Foo to be covariant.
Alternatively, if you don't care about the bound on T:
case class Foo[+T[_]](a: Int, b: String, c: T[Boolean], d: T[Double])
then you can use Foo[Unprocessed] or Foo[Processed] when you need a Foo[Option].
scala> val foo: Foo[Option] = processed
foo: Acme.Foo[Option] = Foo(42,b,Some(true),Some(42.0))
One other strategy might be to create yet another case class:
case class Foo(
id: Int,
bar_id: Int,
baz_id: Int,
x: Int,
y: String
)
case class ProcessedFoo(
foo: Foo,
bar: Bar,
baz: Baz
)
Do you know if ActionScript support union type? For example, something like that:
function foo(x:ClassA Union classB) {
//x is classA or classB
//do something
}
Thanks in advance
Actionscript 3 does not support c++ style mixin class hierarchies.
As3 rather uses the Interface approach that is utilized in many object oriented languages.
An Interface generally is an abstract template of functionality allowing communication between objects which are unrelated in respect of class hierarchy.
such as:
public interface IBox{
function addContentToBox(contentName:String, content:*) Boolean;
function boxHasContent(contentName:String): Boolean;
function getContentFromBox(contentName:String): *;
}
When you define a class in as3, if you want it to implement IBox Interface you write
class YourClass extends anotherClass implements IBox {
(extends anotherClass is only needed if you are extending another class)
Now you have to write code for functions declared in IBox in YourClass.
Then what is the catch? Well, first of all
a = new YourClass(parameters etc);
if(a is YourClass)trace('YIPPE');
if(a is IBox)trace('YAY');
You have a trace of YIPPE YAY now.
(xxx is IBox) will be true for all instances of all classes implementing IBox.
You can pass any unrelated objects with classes implementing IBox to functions expecting IBox.
Please refer to Adobe as3 interface document for further information.
I hope this helps.
Closest you can get to that is by having a base class A and deriving two classes from it B and C. Then you can pass either B or C instances to the function foo.
class classA {}
class classB extends classA {}
class classC extends classA {}
function foo(x:ClassA)
{
if(x is classB)
trace("x is classB");
else if (x is classC)
trace("x is classC");
}
var c:ClassC = new ClassC();
foo(c);
Though I wouldn't suggest checking types of classes and executing code based on that, using an interface would probably help you out, but we would need to know what you are trying to do.
It seems empowering that one can effectively make assertions about legal return values of implementing methods just based on the type of the abstract function/method.
I intuitively feel (most of) the compiler behaviour below makes sense but I would appreciate a clear explanation of why I should be able to assert that
def f[T](t: T): T
can only be the identity function (except that class E compiles too). I can appreciate that we know nothing about T as it is not bounded, but there are gaps in that explanation.
The compiler reporting "found scala.Int(42) required Int" is not getting me closer to the light.
trait A{ def f[T](t: T): T }
// compiles
class B extends A{ override def f[Int](t: Int): Int = t }
// does not compile
class C extends A{ override def f[Int](t: Int): Int = t + 1 }
// does not compile
class D extends A{ override def f[Int](t: Int): Int = 42 }
// compiles
class E extends A{ override def f[Int](t: Int): Int = 42.asInstanceOf[Int] }
// compiles
class F extends A{ override def f[Int](t: Int): Int = identity(t) }
The problem in your examples is that the Int in your examples is not the normal 32-bit integer type (which is scala.Int); instead, you have a type parameter that happens to be named Int. That's confusing you: you think your Int is scala.Int, but it isn't, it's a type parameter with a confusing name.
So, for example this:
class C extends A{ override def f[Int](t: Int): Int = t + 1 }
Does not mean you are defining a method that takes a scala.Int; you're defining a method with a type parameter that has the name Int. You could give it any other name, for example X, then it would be exactly the same:
class C extends A{ override def f[X](t: X): X = t + 1 }
It doesn't compile because there are no constraints on the type parameter, so the compiler doesn't know that the type has a + method.
Jesper has the correct answer with the main question: [Int] isn't filling in a type of Int for T, it's creating a new generic type parameter confusingly named Int.
But I also have an addendum:
You are being a little too trusting that the user won't do something sneaky, even if it's valid at runtime.
def f[T](t: T): T = (t match {
case i: Int => -i
case s: String => s.reverse
case b: Boolean => !b
case o: Option[_] => None
case s: Seq[_] => throw new Exception("Ack")
case _ => t
}).asInstanceOf[T]
Not exactly the identity function any more, is it? If you forbid matches and asInstanceOf and exceptions and so on, then it's got to be identity.
Since nobody's answered the other part of the question yet:
In general, this property is called parametricity, and the guarantees you get from it are called free theorems. This only holds, by the way, if you ignore typecase (and unmarked side effects), so a huge part of Scala doesn't count.
This is very basic question from programming point of view but as I am in learning phase, I thought I would better ask this question rather than having a misunderstanding or narrow knowledge about the topic.
So do excuse me if somehow I mess it up.
Question:
Let's say I have class A,B,C and D now class A has some piece of code which I need to have in class B,C and D so I am extending class A in class B, class C, and class D
Now how can I access the function of class A in other classes, do I need to create an object of class A and than access the function of class A or as am extending A in other classes than I can internally call the function using this parameter.
If possible I would really appreciate if someone can explain this concept with code sample explaining how the logic flows.
Note
Example in Java, PHP and .Net would be appreciated.
Let's forget about C and D because they are the same as B. If class B extends class A, then objects of type B are also objects of type A. Whenever you create an object of type B you are also creating an object of type A. It should have access to all of the methods and data in A (except those marked as private, if your language supports access modifiers) and they can be referred to directly. If B overrides some functionality of A, then usually the language provides a facility to call the base class implementation (base.Foo() or some such).
Inheritance Example: C#
public class A
{
public void Foo() { }
public virtual void Baz() { }
}
public class B : A // B extends A
{
public void Bar()
{
this.Foo(); // Foo comes from A
}
public override void Baz() // a new Baz
{
base.Baz(); // A's Baz
this.Bar(); // more stuff
}
}
If, on the other hand, you have used composition instead of inheritance and B contains an instance of A as a class variable, then you would need to create an object of A and reference it's (public) functionality through that instance.
Composition Example: C#
public class B // use A from above
{
private A MyA { get; set; }
public B()
{
this.MyA = new A();
}
public void Bar()
{
this.MyA.Foo(); // call MyA's Foo()
}
}
depending on the access level (would be protected or public in .NET), you can use something like:
base.method(argumentlist);
the base keyword in my example is specific to C#
there is no need for an instance of class A, because you already have a class A inherited instance
Basically you need a reference to the parent class.
In PHP:
parent::example();
From: http://www.php.net/manual/en/keyword.parent.php
<?php
class A {
function example() {
echo "I am A::example() and provide basic functionality.<br />\n";
}
}
class B extends A {
function example() {
echo "I am B::example() and provide additional functionality.<br />\n";
parent::example();
}
}
$b = new B;
// This will call B::example(), which will in turn call A::example().
$b->example();
?>
I find that the best way to tame the complexity of inheritance is to ensure that I only make B inherit from A when it really is a specialization of the superclass. At that point, I can call A's methods from inside B just as if they were B's own methods, and if B has overridden them then I can only suppose that this must be for a good reason.
Of course, quite often it is useful for B's implementation of a method to invoke A's implementation on the same object, generally because the subclass is wrapping extra behavior around the superclass's basic definition. The way in which you do this varies between languages; for example, in Java you do this:
super.methodName(arg1, ...);
Here's a quick Java example:
public class Aclass
{
public static void list_examples()
{
return("A + B = C");
}
}
public class Bclass extends Aclass
{
public static void main(String [] args)
{
System.out.println("Example of inheritance "+list_examples);
}
}
Note that the method for accessing the parent class shouldn't change. Because you are extending you shouldn't have to say parent:: or anything unless you are overriding the parent method / function.
It seems to me that extending your class might not be your best option. Class "B", "C", and "D" should only extend class "A" if they are truly an extension of that class, not just to access some method. For instance "Huffy" should not extend "BrandNames" just because "Huffy" is a brand name and you want access to one of the methods of "BrandNames". "Huffy" should instead extend "Bicycle" and implement an interface so the methods of "BrandNames" can be used. An additional benefit here is that (in Java) multiple interfaces can be used but a class can only be extended once. If in your example class "B"' needed to access a method from class "A" that could work, but if class "C" needed to access a method from class "A" and class "'B"' then you would have to use an interface in class "'C".