I'm trying to understand what monads are in Scala.
Say for example I have methods in Java like this:
public void doSomeThing()
{
a.call();
}
public void doOtherThing()
{
a2.call();
}
public void doSomeOtherThing()
{
a3.call();
}
All the methods that starts with do, just only do the method call named call. If I convert that into a common method in Java like:
public void doGeneric(SomeClass a)
{
a.call();
}
and say this as a generic method, with does the call function, then doGeneric is an monad? Correct me if I'm wrong.
Note that I gave the examples in Java, as I'm just now starting with Scala.
Monad is associated to the notion of "container" like Option or List.
Basically, a container that defines the flatMap method is a monad:
trait Monad[A] { //let's say a Monad container to be general. A well-known would be Option
def flatMap[B](f: A => Monad[B]): Monad[B]
}
In your case, you simply call a method on one object.
You are not computing a "container"'s value from another container, so you haven't got a monad.
Indeed, you just make use of polymorphism.
Related
I have multiple types with similar methods. I want to abstract over them by writing an interface, like I would in Java:
public interface Shape {
public float area();
}
class Circle implements Shape {
public float area() {
return radius * radius * Math.PI;
}
public float radius;
}
However, there is no interface keyword in Rust. Doesn't Rust offer the possibility to abstract over multiple types?
TL;DR: The closest to interface in Rust is a trait. However, do not expect it to be similar in all point to an interface. My answer does not aim to be exhaustive but gives some elements of comparison to those coming from other languages.
If you want an abstraction similar to interface, you need to use Rust's traits:
trait Shape {
fn area(&self) -> f32;
}
struct Circle {
radius: f32,
}
impl Shape for Circle {
fn area(&self) -> f32 {
self.radius.powi(2) * std::f32::consts::PI
}
}
struct Square {
side: f32,
}
impl Shape for Square {
fn area(&self) -> f32 {
self.side.powi(2)
}
}
fn main() {
display_area(&Circle { radius: 1. });
display_area(&Square { side: 1. });
}
fn display_area(shape: &dyn Shape) {
println!("area is {}", shape.area())
}
However, it is an error to see a Rust trait as an equivalent of OOP interface. I will enumerate some particularities of Rust's traits.
Dispatch
In Rust, the dispatch (i.e. using the right data and methods when given a trait) can be done in two ways:
Static dispatch
When a trait is statically dispatched, there is no overhead at runtime. This is an equivalent of C++ templates; but where C++ uses SFINAE, the Rust compiler checks the validity using the "hints" we give to him:
fn display_area(shape: &impl Shape) {
println!("area is {}", shape.area())
}
With impl Shape, we say to the compiler that our function has a generic type parameter that implements Shape, therefore we can use the method Shape::area on our shape.
In this case, like in C++ templates, the compiler will generate a different function for each different type passed in.
Dynamic dispatch
In our first example:
fn display_area(shape: &dyn Shape) {
println!("area is {}", shape.area())
}
the dispatch is dynamic. This is an equivalent to using an interface in C#/Java or an abstract class in C++.
In this case, the compiler does not care about the type of shape. The right thing to do with it will be determined at runtime, usually at a very slight cost.
Separation between data and implementation
As you see, the data is separated from the implementation; like, for example, C# extension methods. Moreover, one of the utilities of a trait is to extend the available methods on a value:
trait Hello {
fn say_hello(&self);
}
impl Hello for &'static str {
fn say_hello(&self) {
println!("Hello, {}!", *self)
}
}
fn main() {
"world".say_hello();
}
A great advantage of this, is that you can implement a trait for a data without modifying the data. In contrast, in classical object oriented languages, you must modify the class to implement another interface. Said otherwise, you can implement your own traits for external data.
This separation is true also at the lowest level. In case of dynamic dispatch, the method is given two pointers: one for the data, and another for the methods (the vtable).
Default implementation
The trait has one more thing than a classic interface: it can provide a default implementation of a method (just like the "defender" method in Java 8). Example:
trait Hello {
fn say_hello(&self) {
println!("Hello there!")
}
}
impl Hello for i32 {}
fn main() {
123.say_hello(); // call default implementation
}
To use classic OOP words, this is like an abstract class without variable members.
No inheritance
The Rust trait's system is not an inheritance system. You cannot try to downcast, for example, or try to cast a reference on a trait to another trait. To get more information about this, see this question about upcasting.
Moreover, you can use the dynamic type to simulate some behavior you want.
While you can simulate the inheritance mechanism in Rust with various tricks, this is a better idea to use idiomatic designs instead of twist the language to a foreign way of thinking that will uselessly make grow the complexity of code.
You should read the chapter about traits in the Rust book to learn more about this topic.
How to call such a scala function?
def f(v: Void): Unit = {println(1)}
I haven't found a value of Void type in Scala yet.
I believe using Void/null in Java is similar to using Unit/() in Scala. Consider this:
abstract class Fun<A> {
abstract public A apply();
}
class IntFun extends Fun<Integer> {
public Integer apply() { return 0; }
}
public static <A> A m(Fun<A> x) { return x.apply(); }
Now that we defined generic method m we also want to use it for classes where apply is only useful for its side effects (i.e. we need to return something that clearly indicates it's useless). void doesn't work as it breaks Fun<A> contract. We need a class with only one value which means "drop return value", and it's Void and null:
class VoidFun extends Fun<Void> {
public Void apply() { /* side effects here */ return null; }
}
So now we can use m with VoidFun.
In Scala usage of null is discouraged and Unit is used instead (it has only one value ()), so I believe the method you mentioned was intended to be called from Java. To be compatible with Java Scala has null which is the only instance of a class Null. Which in turn is a subtype of any reference class, so you can assign null to any reference class variable. So the pattern Void/null works in Scala too.
Void, or more specifically, java.lang.Void, has the following in the documentation:
The Void class is an uninstantiable placeholder class to hold a
reference to the Class object representing the Java keyword void.
In Scala, there's no keyword void, so the Void type is essentially useless in Scala. The closest thing is either a function with no parameters, i.e. def f: Unit = {println(1)} which you can call using f or f(), or the Unit type for functions that don't return anything, as in your example.
I have the following setup:
trait A
{
def doSomething(): Unit;
}
object B extends A
{
override def doSomething(): Unit =
{
// Implementation
}
}
class B(creator: String) extends A
{
override def doSomething(): Unit =
{
B.doSomething() // Now this is just completely unnecessary, but the compiler of course insists upon implementing the method
}
}
Now you may wonder why I even do this, why I let the class extend the trait as well.
The problem is, that somewhere in the Program there is a Collection of A.
So somewhere:
private val aList: ListBuffer[A] = new ListBuffer[A]
and in there, I also have to put Bs (among other derivates, namely C and D)
So I can't just let the B-class not extend it.
As the implementation is the same for all instances, I want to use an Object.
But there is also a reason I really need this Object. Because there is a class:
abstract class Worker
{
def getAType(): A
def do(): Unit =
{
getAType().doSomething()
}
}
class WorkerA
{
def getAType(): A =
{
return B
}
}
Here the singleton/object of B gets returned. This is needed for the implementation of do() in the Worker.
To summarize:
The object B is needed because of the generic implementation in do() (Worker-Class) and also because doSomething() never changes.
The class B is needed because in the collection of the BaseType A there are different instances of B with different authors.
As both the object and the class have to implement the trait for above reasons I'm in kind of a dilemma here. I couldn't find a satisfying solution that looks neater.
So, my question is (It turns out as a non-native-speaker I should've clarified this more)
Is there any way to let a class extend a trait (or class) and say that any abstract-method implementation should be looked up in the object instead of the class, so that I must only implement "doSomething()" (from the trait) once (in the object)? As I said, the trait fulfills two different tasks here.
One being a BaseType so that the collection can get instances of the class. The other being a contract to ensure the doSomething()-method is there in every object.
So the Object B needs to extend the trait, because a trait is like a Java interface and every (!) Object B (or C, or D) needs to have that method. (So the only option I see -> define an interface/trait and make sure the method is there)
edit: In case anyone wonders. How I really solved the problem: I implemented two traits.
Now for one class (where I need it) I extend both and for the other I only extend one. So I actually never have to implement any method that is not absolutely necessary :)
As I wrote in the comment section, it's really unclear to me what you're asking.
However, looking at your code examples, it seems to me that trait A isn't really required.
You can use the types that already come with the Scala SDK:
object B extends (()=>Unit) {
def apply() { /* implementation */ }
}
Or, as a variant:
object B {
val aType:()=>Unit = {() => /* implementation */ }
}
In the first case, you can access the singleton instance with B, in the second case with B.aType.
In the second case, no explicit declaration of the apply method is needed.
Pick what you like.
The essential message is: You don't need a trait if you just define one simple method.
That's what Scala functions are for.
The list type might look like this:
private val aList:ListBuffer[()=>Unit] = ???
(By the way: Why not declare it as Seq[()=>Unit]? Is it important to the caller that it is a ListBuffer and not some other kind of sequence?)
Your worker might then look like this:
abstract class Worker {
def aType:()=>Unit // no need for the `get` prefix here, or the empty parameter list
def do() {aType()}
}
Note that now the Worker type has become a class that offers a method that invokes a function.
So, there is really no need to have a Worker class.
You can just take the function (aType) directly and invoke it, just so.
If you always want to call the implementation in object B, well - just do that then.
There is no need to wrap the call in instances of other types.
Your example class B just forwards the call to the B object, which is really unnecessary.
There is no need to even create an instance of B.
It does have the private member variable creator, but since it's never used, it will never be accessed in any way.
So, I would recommend to completely remove the class B.
All you need is the type ()=>Unit, which is exactly what you need: A function that takes no parameters and returns nothing.
If you get tired of writing ()=>Unit all the time, you can define a type alias, for example inside the package object.
Here is my recommentation:
type SideEffect = ()=>Unit
Then you can use SideEffect as an alias for ()=>Unit.
That's all I can make of it.
It looks to me that this is probably not what you were looking for.
But maybe this will help you a little bit along the way.
If you want to have a more concrete answer, it would be nice if you would clarify the question.
object B doesn't really have much to do with class B aside from some special rules.
If you wish to reuse that doSomething method you should just reuse the implementation from the object:
class B {
def doSomething() = B.doSomething()
}
If you want to specify object B as a specific instance of class B then you should do the following:
object B extends B("some particular creator") {
...
}
You also do not need override modifiers although they can be handy for compiler checks.
The notion of a companion object extending a trait is useful for defining behavior associated with the class itself (e.g. static methods) as opposed to instances of the class. In other words, it allows your static methods to implement interfaces. Here's an example:
import java.nio.ByteBuffer
// a trait to be implemented by the companion object of a class
// to convey the fixed size of any instance of that class
trait Sized { def size: Int }
// create a buffer based on the size information provided by the
// companion object
def createBuffer(sized: Sized): ByteBuffer = ByteBuffer.allocate(sized.size)
class MyClass(x: Long) {
def writeTo(buffer: ByteBuffer) { buffer.putLong(x) }
}
object MyClass extends Sized {
def size = java.lang.Long.SIZE / java.lang.Byte.SIZE
}
// create a buffer with correct sizing for MyClass whose companion
// object implements Sized. Note that we don't need an instance
// of MyClass to obtain sizing information.
val buf = createBuffer(MyClass)
// write an instance of MyClass to the buffer.
val c = new MyClass(42)
c.writeTo(buf)
I've been searching for a while and can't seem to find something that matches exactly what I need.
I want to have a way to wrap any class (let's say T) with something that would "do something cool" before and after each invocation of the public methods of this T class, and this thing would look like T to the compiler.
Here's some pseudo code to illustrate:
object CoolWrap {
def apply[T](underlying: T) {
new CoolWrapImpl(underlying).asInstanceOf[T]
}
}
class CoolWrapImpl[T](underlying: T) extends T {
def onPublicMethod(method: Method, params: Params) = {
// method would be the method that was invoked on T
doSomethingCool1(params) // like logging
val resp = measureTime { method.invoke(params) }
doAnotherCoolThing()
resp
}
}
Using reflection is not out of the question, this would only happen once per instance that would live in memory throughout the life of the process, so I'm not concerned with it being slow to instantiate.
Is this even possible? (currently forced to use Scala 2.9.2)
Thanks!
I'm trying to use the scaffolding described by oxbow_lakes in What is the easiest way to implement a Scala PartialFunction in Java? to call a Scala method that takes a PartialFunction. Here's my Scala code:
class MyScalaClass {
def instanceOfSomeType: SomeType = ...
def consume(processor: PartialFunction[SomeType, Unit]) {
processor.lift(instanceOfSomeType)
}
}
And here's how I'm trying to call it from Java:
MyScalaClass myScalaClass = new MyScalaClass();
PartialTransformer<SomeType, Unit> fn = new PartialTransformer<SomeType, Unit>() {
#Override public boolean isDefinedAt(SomeType input) { return true; }
#Override protected Unit transform0(SomeType input) { return null; }
};
PartialFunction<SomeType, Unit> partial = PartialFunctionBridge$.MODULE$.fromPartialTransformer(fn);
myScalaClass.consume(partial);
The compiler tells me:
consumeInt(scala.PartialFunction<SomeType,java.lang.Object>) in MyScalaClass cannot be applied
to (scala.PartialFunction<SomeType,scala.Unit>)
Use void as return types in Java to correspond to Unit in Scala. Use scala.Unit for actual type parameters in generics.
Update
I was wrong. You cannot use void on the Java side to correspond to Unit on the Scala side. That's another fiction Scala provides in the reverse direction.
Working on it...
Update 2
It seems a lot of methods marked concrete in PartialFunction are created by the compiler. This is proving a lot more tedious than I thought and work beckons.
As usual, accessing Scala from Java is a lot harder than the reverse. Perhaps you can create a Java-friendly API on your Scala side?