Scala, cats - how to do not use Applicative[F] explicity? - scala

I would like to use Applicative[F] in some other way then explicity. Currently I have a simple code:
class BettingServiceMock[F[_] : Async] extends BettingService[F] {
override def put(bet: Bet): F[Bet] = {
for {
created <- Bet(Some(BetId(randomUUID().toString)), bet.stake, bet.name).pure
} yield created
}
}
Bet is just a simple case class. I use method pure explicity to return F[Bet]. Is there some way to do not it like this way (to do not call pure method explicity)?
I tried to do something like this:
class BettingServiceMock[F[_] : Async] (implicit a:Applicative[F]) extends BettingService[F] {
override def put(bet: Bet): F[Bet] = {
for {
created <- Bet(Some(BetId(randomUUID().toString)), bet.stake, bet.name)
} yield created
}
}
It did not help, because I got an error:
value map is not a member of model.Bet <- (Some(BetId(randomUUID().toString)), bet.stake, bet.name)
I would like to discover some good practise in Cats that's way I'm asking about it. I do not thnik so that explicity call methids like pure is good practise. Could you help me with that?

First of all, why do you think it's a bad practice. That's a common Applicative syntax. If you want some "magic" automatically lifts your value Bet to Applicative[Bet] then you would need sort of implicit conversion and that would be really bad practice.
You take a look at the scaladoc example of Applicative https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/Applicative.scala
Applicative[Option].pure(10)
Here the Applicative[Option] instance was summoned by apply[F[_]](implicit instance: Applicative[F]) which is automatically generated by simulacrum's #typeclass.

Related

Compile time structural typing of close method

I've got the following helper method in my project:
def close(c: Closeable) {
Option(c).foreach(s => Try(s.close))
}
I've got some classes that have a close method but do not implement Closeable. If I change the helper method to use structural types I can still use it on these classes:
def close(c: {def close()}) {
Option(c).foreach(s => Try(s.close))
}
However this introduces use of reflection which is something that I'd like to avoid in runtime.
Is there a way to use something similar to structural typing without inducing runtime reflection?
I.e in the same way Shapeless allows generic access to fields, maybe implicit parameters + macros could be used to access methods in the same way?
Use traits to implement the typeclass pattern.
When I wrote my original solution it was a bit rough round the edges as I assumed a quick search for convert structural bounds to context bounds would pull up better explanations than I could write. That doesn't seem to be the case. Below is a compiling solution.
object Closeables {
trait MyCloseable[A] {
def myClose(a: A): Unit
}
object MyCloseable {
implicit object MyCanBeClosed extends MyCloseable[CanBeClosed] {
def myClose(c: CanBeClosed) = c.nonStandardClose()
}
}
}
class CanBeClosed {
def nonStandardClose(): Unit = println("Closing")
}
import Closeables._
object Test extends App {
def functionThatCloses[A: MyCloseable](a: A) {
implicitly[MyCloseable[A]].myClose(a)
}
def functionThatClosesExplicit[A](a: A)(implicit ev: MyCloseable[A]) {
ev.myClose(a)
}
val c = new CanBeClosed
functionThatCloses(c)
functionThatClosesExplicit(c)
functionThatCloses(c)(MyCloseable.MyCanBeClosed)
functionThatClosesExplicit(c)(MyCloseable.MyCanBeClosed)
}
For each type of class that can be accepted by functionThatCloses you must define and implicit object in MyCloseables.
The compiler looks at the context bound in functionThatCloses and converts it to a function with the definition of functionThatClosesExplicitly.
The compiler than 'finds' the implicit 'evidence' in the definition from the MyCloseables object and uses that.

Spark: Custom operator for JavaPairRDD

I'm trying to declare a custom operator for JavaPairRDD, here is the code:
object CustomOperators {
implicit class CustomRDDOperator[K: ClassTag, V: ClassTag](rdd: JavaPairRDD[K, V]) {
def customOp = {
// logic
}
}
}
But I'm not able to call this function from my JavaPairRDD.
I'm very new to Scala, so there is a good chance that I'm doing something fundamentally wrong. Need some guidance.
What would be the best way to add a custom function to JavaPairRDD?
You should just need to add import CustomOperators._ in the file where you are using it. But if you are working from Scala, you shouldn't end up with a JavaPairRDD in the first place (unless you are using third-party library intended to be used primarily from Java).

Preserve type/class tag among akka messages

I have the situation where I want to preserve information about some generic type passed within a message to be able to create another generic class with that same type within receive method responsible for processing the message.
At first glance I thought TypeTag is my best friend here, but, after trying that out it seems this is not the best possible solution, or not solution at all. Let me first explain what I have at the moment and what is the outcome.
Message case class
trait MessageTypeTag[T] {
def typeTag: TypeTag[T]
}
case class Message[T](id: Int, payload: T, helper: MyClass[T],
cond: Condition[MyClass[T]])(implicit val typeTag: TypeTag[T])
extends MessageTypeTag[T]
MyClass2
class MyClass2[+T <: Any](_eval: Option[T] = None) {
def getEval = _eval getOrElse None
}
Receive method
def receive() = {
case m#Message(id, payload, helper, cond) => {
// this prints a proper type tag, i.e. String, because type is known in the runtime
println(m.typeTag.tpe)
// compiler complains here because it sees m.typeTag as TypeTag[Any], i.e. exact
// type is not known in the compile time
val temp = new MyClass2[m.typeTag.tpe](...)
}
}
Dirty solution
After reading several articles, discussions, documentation on both Scala and akka I come up with some dirty solution by putting the (call to) factory method case class.
case class Message[T](id: Int, payload: T, helper: MyClass[T],
cond: Condition[MyClass[T]])(implicit val typeTag: TypeTag[T])
extends MessageTypeTag[T] {
def getMyClass2: MyClass2[T] = {
// instantiate an object of type T
val bla = typeTag.mirror.runtimeClass(typeTag.tpe).newInstance.asInstanceOf[T]
// we can call apply here to populate created object or do whathever is needed
...
// instantiate MyClass2 parametrized with type T and return it
new MyClass2[T](Some(bla))
}
}
As you can see this is far from good solution/design because this case class is all but lightweight and actually defeats the purpose of case class itself. It can be improved in a way that reflection call is not coded here but in some external factory which is just called within case class, but I have a feeling there must be a better approach to accomplish this.
Any suggestion would be very appreciated. If there are some more information needed, I can provide it.
And, I believe, similar problem/solution has been described here, but I'm wondering is there a better way. Thanks.
If you want to be able to instantiate a class with reflection then you have to pass it around, there's no way around that. I think a ClassTag based solution is slightly simpler:
val bla = classTag.runtimeClass.newInstance.asInstanceOf[T]
but it's still pretty ugly.
It might be better to pass around a factory as a function rather than using a reflective approach; this lets you work with classes with no no-arg constructor or that require some setup:
case class Message[T](..., factory: () => T) {
def getMyClass2 = new MyClass2[T](Some(factory()))
}
Message(..., {_ => new SomeTThatTakesArguments(3, 4)})
I suspect the best solution will be to change your MyClass2 so that it doesn't depend on the type in the same way - perhaps you can express the constraint MyClass2 needs as a typeclass you can include in the Message, or leave it out entirely. But you'll need to post MyClass2 if you want us to suggest a solution on those lines.

How can I add new methods to a library object?

I've got a class from a library (specifically, com.twitter.finagle.mdns.MDNSResolver). I'd like to extend the class (I want it to return a Future[Set], rather than a Try[Group]).
I know, of course, that I could sub-class it and add my method there. However, I'm trying to learn Scala as I go, and this seems like an opportunity to try something new.
The reason I think this might be possible is the behavior of JavaConverters. The following code:
class Test {
var lst:Buffer[Nothing] = (new java.util.ArrayList()).asScala
}
does not compile, because there is no asScala method on Java's ArrayList. But if I import some new definitions:
class Test {
import collection.JavaConverters._
var lst:Buffer[Nothing] = (new java.util.ArrayList()).asScala
}
then suddenly there is an asScala method. So that looks like the ArrayList class is being extended transparently.
Am I understanding the behavior of JavaConverters correctly? Can I (and should I) duplicate that methodology?
Scala supports something called implicit conversions. Look at the following:
val x: Int = 1
val y: String = x
The second assignment does not work, because String is expected, but Int is found. However, if you add the following into scope (just into scope, can come from anywhere), it works:
implicit def int2String(x: Int): String = "asdf"
Note that the name of the method does not matter.
So what usually is done, is called the pimp-my-library-pattern:
class BetterFoo(x: Foo) {
def coolMethod() = { ... }
}
implicit def foo2Better(x: Foo) = new BetterFoo(x)
That allows you to call coolMethod on Foo. This is used so often, that since Scala 2.10, you can write:
implicit class BetterFoo(x: Foo) {
def coolMethod() = { ... }
}
which does the same thing but is obviously shorter and nicer.
So you can do:
implicit class MyMDNSResolver(x: com.twitter.finagle.mdns.MDNSResolver) = {
def awesomeMethod = { ... }
}
And you'll be able to call awesomeMethod on any MDNSResolver, if MyMDNSResolver is in scope.
This is achieved using implicit conversions; this feature allows you to automatically convert one type to another when a method that's not recognised is called.
The pattern you're describing in particular is referred to as "enrich my library", after an article Martin Odersky wrote in 2006. It's still an okay introduction to what you want to do: http://www.artima.com/weblogs/viewpost.jsp?thread=179766
The way to do this is with an implicit conversion. These can be used to define views, and their use to enrich an existing library is called "pimp my library".
I'm not sure if you need to write a conversion from Try[Group] to Future[Set], or you can write one from Try to Future and another from Group to Set, and have them compose.

How to declare anonymous mixin using a type parameter in Scala

There have been some questions asked that are somewhat related to this problem, but they don't seem to fit quite right.
I'm using the Cake pattern to slide a "Storage" system in place in production code, and a stub storage system in for testing purposes. This is all great, but there's a class that's being instantiated within the original class that also needs to have this stub storage system mixed in. Since it's hidden inside the implementation, I don't have access to it.
Things look like this:
class Main { this: Storage =>
...
val used = Used(...)
...
}
class Used { this: Storage =>
...
}
When testing "Used" I simply new Used with StubStorage and off I go. I used to do the same with Main but that was before it made use of Used. Now that Main makes a naive instantiation of Used I've got this problem.
I wanted to try it this way:
class Main[T <: Storage] { this: T =>
...
val used = Used[T](...)
...
}
class Used[T <: Storage] { this: T =>
...
}
object Used {
def apply[T <: Storage](...) = new Used(...) with T
}
But of course that doesn't work because the compiler doesn't have enough information to discover T. Is there a magic recipe for this? I've played around with it for a bit and it seems to be cumbersome enough that the standard OO injection method is actually less trouble, but I could be missing something.
I've looked at the implicit Factory concept but I can't pound that into shape to work for mixins.
EDIT: It's amazing the clarity that writing the question publicly gives. :) I haven't solved the problem the way I originally intended, but there is a simple solution to the actual problem:
trait UsedProvider {
def createUsed = Used.apply _
}
class Main { this: Storage with UsedProvider =>
val used = createUsed(...)
}
Then I would just do the following in the test: new Main with StubStorage with StubUsedProvider.
I haven't solved your original problem either but have you considered using an abstract class for Main and provide the value for used where you need it?
abstract class Main { this: Storage =>
val s = "s"
val used: Used
}
Then instantiate like this:
val main = new Main with StubStorage { val used = new Used(s) with StubStorage }