Lift uses a PartialFunction on their implementation of Comet Actors, and you usually end up with this on your class:
override def lowPriority: PartialFunction[Any,Unit] = {
case MyCaseClass1(a) => do something here
case MyCaseClass2(a) => do something here
case AlwaysPresentCaseClass => default action
}
What I'd like to do, and I'm not sure if it is even possible is to split that Partial Function so that the last case can be moved into a trait.
So when I have a new comet actor I simply do:
class MyNewComet extends MyActorTrait {
override def lowPriority: PartialFunction[Any,Unit] = {
case MyCaseClass1(a) => do something here
case MyCaseClass2(a) => do something here
}
}
And Somehow the trait MyActorTrait will have the missing
case AlwaysPresentCaseClass => default action
You can compose partial functions using the orElse method:
val f1: PartialFunction[Any, String] = {
case 22 => "hallo"
}
val f2: PartialFunction[Any, String] = {
case "rara" => "welt"
}
val f = f1 orElse f2 // f falls back to f2 if undefined in f1
f(22)
f("rara")
Try this:
trait MyActorTrait extends /* whatever class provides lowPriority */ {
def default: PartialFunction[Any, Unit] = {
case AlwaysPresentCaseClass => default action
}
abstract override def lowPriority: PartialFunction[Any,Unit] =
super.lowPriority orElse default
}
The only problem is that you can't do MyNewComet extends MyActorTrait. Instead, you can either have class MyNewCometDefault extends MyNewComet with MyActorTrait, or new MyNewComet with MyActorTrait.
Related
we are given a linked list class, and we need to create a function in this class which takes a function as a parameter, and calls that function on each node of the list. we can do it recursively or through loops and I'm not sure why I can't get this to work.
currently im using a while loop where if the node doesent equal null call the function on that node, and then goto the next node.
class LinkedListNode[A](var value: A, var next: LinkedListNode[A]) {
def calleachnode(inputfunction : A => Unit): Unit = {
var node = this
while(node != null){
inputfunction(node.value)
node = node.next
}
}
}
This type of task is best done with (tail) recursion (also, never use var, unless you are completely certain why you need it ... and also, null is also something to avoid, use Option instead):
case class Node[A](value: A, next: Option[Node[A]]) {
#tailrec
final def calleachnode(f: A => Unit): Unit = {
f(value)
next match {
case Some(next) => next.calleachnode(f)
case None => ()
}
}
}
Here are 3 possibilities that uses Algebraic Data Types (ADT).
First an object-oriented way:
sealed trait LinkedListNode[A] {
def calleachnode(inputfunction : A => Unit): Unit
}
case class BranchNode[A](value:A, next: LinkedListNode[A]) extends LinkedListNode[A] {
def calleachnode(inputfunction : A => Unit): Unit = {
inputfunction(value)
next.calleachnode(inputfunction)
}
}
case class LeafNode[A](value:A) extends LinkedListNode[A] {
def calleachnode(inputfunction : A => Unit): Unit = {
inputfunction(value)
}
}
Or if you prefer you can use pattern matching:
sealed trait LinkedListNode[A] {
def calleachnode(inputfunction : A => Unit): Unit = this match {
case BranchNode(value, next) =>
inputfunction(value)
next.calleachnode(inputfunction)
case LeafNode(value) =>
inputfunction(value)
}
}
case class BranchNode[A](value:A, next: LinkedListNode[A]) extends LinkedListNode[A]
case class LeafNode[A](value:A) extends LinkedListNode[A]
You can test these solutions with:
val lln = BranchNode(12, LeafNode(2))
lln.calleachnode((i) => println(i * 2))
Now a more functional way to use ADT:
sealed trait LinkedListNode[A]
case class BranchNode[A](value:A, next: LinkedListNode[A]) extends LinkedListNode[A]
case class LeafNode[A](value:A) extends LinkedListNode[A]
def calleachnode[A](listNode: LinkedListNode[A], inputfunction : A => Unit): Unit = listNode match {
case BranchNode(value, next) =>
inputfunction(value)
calleachnode(next, inputfunction)
case LeafNode(value) =>
inputfunction(value)
}
The test looks a bit different:
val lln = BranchNode(12, LeafNode(2))
calleachnode[Int](lln, (i) => println(i * 2))
I am trying to learn how to use FreeMonads to implement interpreters for my services.
Suppose I have
sealed trait ServiceAction[T] extends Product with Serializable
case class ConsumeCommand(cmd: AccruePoints) extends ServiceAction[AccruePointModel]
case class CreateEvent(evt: PointsAccruedEvent) extends ServiceAction[PointsAccruedEvent]
sealed trait LogAction[T] extends Product with Serializable
case class Info(msg: String) extends LogAction[Unit]
case class Error(msg: String) extends LogAction[Unit]
and a Monad of the action
type LogActionF[A] = Free[LogAction, A]
type ServiceActionF[A] = Free[ServiceAction, A]
Next, I define my service like this:
trait PointAccrualService {
def consume(cmd: AccruePoints): ServiceActionF[AccruePointModel] = Free.liftF(ConsumeCommand(cmd))
def emit(evt: PointsAccruedEvent) : ServiceActionF[PointsAccruedEvent] = Free.liftF(CreateEvent(evt))
}
and
trait LogService {
def info(msg: String) : LogActionF[Unit] = Free.liftF(Info(msg))
def error(msg: String) : LogActionF[Unit] = Free.liftF(Error(msg))
}
with an object of each
object LogService extends LogService
object PointAccrualService extends PointAccrualService
My LogServiceInterpreter is like this:
case class LogServiceConsoleInterpreter() extends LogServiceInterpreter {
def apply[A](action: LogActionF[A]): Task[A] = action.foldMap(handler)
protected def handler = new (LogAction ~> Task) {
override def apply[A](fa: LogAction[A]) = fa match {
case Info(m) =>
now(info(m))
case Error(m) =>
now(error(m))
}
}
def info(msg: String): Unit = {
println(s"INFO: $msg")
}
def error(msg: String): Unit = {
println(s"ERROR: $msg")
}
}
Similarly, my PointAccuralServiceInterpreter is like this:
case class PointAccuralServiceInterpreter() {
def apply[A] (action: ServiceActionF[A]) : Task[A] = action.foldMap(handler)
protected def handler = new (ServiceAction ~> Task) {
override def apply[A](fa: ServiceAction[A]): Task[A] = fa match {
case ConsumeCommand(cmd) => {
println("Service ConsumeCommand:" + cmd)
now(cmd)
}
case CreateEvent(evt) => {
println("Service CreateEvent:" + evt)
now(evt)
}
}
}
}
My logic is straightforward, I want to log, and consume my command and then create an event, sort of like an event sourcing:
val ret = for {
_ <- logService.info("Command: " + cmd)
model <- service.consume(cmd)
_ <- logService.info("Model: " + model)
evt <- service.emit(model.toEvent("200", "Event Sent"))
_ <- logService.info("Event:" + evt)
} yield evt
This code doesn't even compile actually.
What should I do from here? I think I am supposed to use Coproduct to chain them and execute this piece of logic by feeding my interpreter.
I found something here
https://groups.google.com/forum/#!topic/scalaz/sHxFsFpE86c
or it's said I can use Shapeless to do so
Folding a list of different types using Shapeless in Scala
They are all too complicated. All I want is, after I define my logic, how do I execute it?
Hope I put enough details here for an answer. I really want to learn this. Thanks
I slightly modified your code to create a self-contained running example. I also added a possible answer to your question, how to execute your program, following RĂșnar Bjarnason's ideas, using Scalaz 7.2. (I did not find the or operator for the natural transformations in Scalaz, so I added it here.)
I also added a few stubs to give your actions something to fiddle with and simplified your services to the handlers inside (since I had to create a new service for both languages combined). Furthermore I changed your Task.now{...} to Task{...} to create an asynchronous Task, which is executed on the last line of code.
Here is the full code:
import scala.language.{higherKinds, implicitConversions}
import scalaz._
import scalaz.concurrent.Task
/* Stubs */
case class AccruePoints()
case class AccruePointModel(cmd: AccruePoints) {
def toEvent(code: String, description: String): PointsAccruedEvent = PointsAccruedEvent(code, description)
}
case class PointsAccruedEvent(code: String, description: String)
/* Actions */
sealed trait ServiceAction[T] extends Product with Serializable
case class ConsumeCommand(cmd: AccruePoints) extends ServiceAction[AccruePointModel]
case class CreateEvent(evt: PointsAccruedEvent) extends ServiceAction[PointsAccruedEvent]
sealed trait LogAction[T] extends Product with Serializable
case class Info(msg: String) extends LogAction[Unit]
case class Error(msg: String) extends LogAction[Unit]
/* Handlers */
object PointAccuralServiceHandler extends (ServiceAction ~> Task) {
override def apply[A](fa: ServiceAction[A]): Task[A] = fa match {
case ConsumeCommand(cmd) => {
println("Service ConsumeCommand:" + cmd)
Task(consume(cmd))
}
case CreateEvent(evt) => {
println("Service CreateEvent:" + evt)
Task(evt)
}
}
def consume(cmd: AccruePoints): AccruePointModel =
AccruePointModel(cmd)
}
case object LogServiceConsoleHandler extends (LogAction ~> Task) {
override def apply[A](fa: LogAction[A]): Task[A] = fa match {
case Info(m) =>
Task(info(m))
case Error(m) =>
Task(error(m))
}
def info(msg: String): Unit = {
println(s"INFO: $msg")
}
def error(msg: String): Unit = {
println(s"ERROR: $msg")
}
}
/* Execution */
class Service[F[_]](implicit I1: Inject[ServiceAction, F], I2: Inject[LogAction, F]) {
def consume(cmd: AccruePoints): Free[F, AccruePointModel] = Free.liftF(I1(ConsumeCommand(cmd)))
def emit(evt: PointsAccruedEvent): Free[F, PointsAccruedEvent] = Free.liftF(I1(CreateEvent(evt)))
def info(msg: String): Free[F, Unit] = Free.liftF(I2(Info(msg)))
def error(msg: String): Free[F, Unit] = Free.liftF(I2(Error(msg)))
}
object Service {
implicit def instance[F[_]](implicit I1: Inject[ServiceAction, F], I2: Inject[LogAction, F]) = new Service[F]
}
def prg[F[_]](implicit service: Service[F]) = {
val cmd = AccruePoints()
for {
_ <- service.info("Command: " + cmd)
model <- service.consume(cmd)
_ <- service.info("Model: " + model)
evt <- service.emit(model.toEvent("200", "Event Sent"))
_ <- service.info("Event:" + evt)
} yield evt
}
type App[A] = Coproduct[ServiceAction, LogAction, A]
def or[F[_], G[_], H[_]](f: F ~> H, g: G ~> H) =
new (({type t[x] = Coproduct[F, G, x]})#t ~> H) {
override def apply[A](c: Coproduct[F, G, A]): H[A] = c.run match {
case -\/(fa) => f(fa)
case \/-(ga) => g(ga)
}
}
val app = prg[App]
val ret = app.foldMap(or(PointAccuralServiceHandler, LogServiceConsoleHandler))
ret.unsafePerformSync
Instead of using overloaded methods in object JSONSourceLoaderUtil, I want to switch to pattern matching style. How do I handle the resultant Try[JValue] and Future[JValue] as F[JValue]?
Imports and case classes,
import scalaz._
import Scalaz._
import org.json4s.JsonAST.{JObject, JValue}
trait DataSource
case class LocalFile(input: File) extends DataSource
case class RemoteResource(url: String, req: JValue) extends DataSource
What I have now,
object JSONSourceLoaderUtil {
def jsonFrom[F[_], S <: DataSource](source: S)(f: S => F[JValue])(implicit ev: Monad[F]): F[JValue] = ev.bind(ev.point(source))(f)
def extractFrom(source: RemoteResource): Future[JValue] = {
Future( ... ).flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input))))
}
def extractFrom(source: LocalFile): Try[JValue] = Parser.parseFromFile(source.input)
}
How do I convert to pattern matching style? Is there a another way to do this if I have painted myself into a corner? Thanks.
object JSONSourceLoaderUtil {
def jsonFrom[F[_], S <: DataSource](source: S)(f: S => F[JValue])(implicit ev: Monad[F]): F[JValue] = ev.bind(ev.point(source))(f)
def extractFrom(source: DataSource): F[JValue] = source match {
case RemoteResource(url, request) => Future( ... )
.flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input))))) // cannot convert Future to F
case LocalFile(input) => Parser.parseFromFile(input) // cannot convert Try to F
}
}
Your desired F depends on the type of the data source. So why not make this explicit?
trait DataSource[F[_]] {
def extract: F[JValue]
}
case class LocalFile(input: File) extends DataSource[Try] {
def extract = Parser.parseFromFile(input)
}
case class RemoteResource(url: String, req: JValue) extends DataSource[Future] {
def extract = Future( ... )
.flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input)))))
}
Removing the extract method and writing
def extractFrom[F[_]](source: DataSource[F]): F[JValue] = source match {
case RemoteResource(url, request) => Future( ... )
.flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input)))))
case LocalFile(input) => Parser.parseFromFile(input)
}
}
should also probably work, at least in Scala 2.12. But I find the first solution to be cleaner.
More specifically, I have:
case class Key (key: String)
abstract class abstr {
type MethodMap = PartialFunction[Key, String => Unit]
def myMap: MethodMap // abstract
def useIt (key: Key, value: String) = {
val meth = myMap(key)
meth(value)
}
def report = {
for (key <- myMap.keySet) // how to do this
println("I support "+key)
}
}
I use it like this:
class concrete extends abstr {
var one: Boolean
def method1(v: String): Unit = ???
def method2(v: String): Unit = ???
def map1: MethodMap = {
case Key("AAA") => method1
}
def map2: MethodMap = {
case Key("AAA") => method2
}
override def myMap: MethodMap = if (one) map1 else map2
}
Of course, this is somewhat simplified, but the report function is necessary.
Some history: I first had it implemented using Map but then I changed it to PartialFunction in order to support the following override def myMap: MethodMap = if (one) map1 else map2.
Any suggestion to refactor my code to support everything is also appreciated.
No. PartialFunction can be defined (and often is) on infinite sets. E.g. what do you expect report to return in these situations:
class concrete2 extends abstr {
def myMap = { case Key(_) => ??? }
}
or
class concrete2 extends abstr {
def myMap = { case Key(key) if key.length > 3 => ??? }
}
? If you have a finite list of values you are interested in, you can do
abstract class abstr {
type MethodMap = PartialFunction[Key, String => Unit]
def myMap: MethodMap // abstract
val keys: Seq[Key] = ...
def report = {
for (key <- keys if myMap.isDefined(key))
println("I support "+key)
}
}
Some history: I first had it implemented using Map but then I changed it to PartialFunction in order to support the last line in second part.
Why? This would work just as well with Map.
In your solution, is there any way to define the domain of the partial function to be the finite set keys
def f: MethodMap = { case key if keys.contains(key) => ... }
Of course, the domain isn't part of the type.
I have a sealed trait:
sealed trait ActorMessage
case class AddX(x: Int) extends ActorMessage
case class RemoveX(x: Int) extends ActorMessage
Also I have a function to handle all messages and warn me about non exhaustive match:
def handleMessage: ActorMessage => Unit = {
case AddX(x) => ...
case RemoveX(x) => ...
}
Actor requires a PartialFunction[Any, Unit]. PartialFunction extends Function which means I can't assign my Function to be PartialFunction.
I have written simple converter:
def liftToPartialFunction[FUND <: PFUND, B, PFUND](f: Function[FUND, B]): PartialFunction[PFUND, B] = new PartialFunction[PFUND, B] {
override def isDefinedAt(x: PFUND): Boolean = x.isInstanceOf[FUND]
override def apply(v1: PFUND): B = f(v1.asInstanceOf[FUND])
}
But is there a better way to do this? Or is there any equivalent in standard scala library?
You can use Function.unlift -
val f: Throwable => Option[String] = {
case e: NullPointerException => Some("nah it's ok")
case e => None
}
Future(null.toString).recover(Function.unlift(f))
// Future(Success(nah it's ok))
I usually do something like this:
override def receive = {
case m: ActorMessage => m match {
// You'll get non-exhaustive match warnings here
case AddX(x) => /* ... */
case RemoveX(x) => /* ... */
}
case m => /* log a warning */
}
Equivalently, using your handleMessage function:
override def receive = {
case m: ActorMessage => handleMessage(m)
case m => /* log a warning */
}
You can just declare handleMessage as a partial function:
def handleMessage: PartialFunction[ActorMessage,Unit] = {
case AddX(x) => ...
case RemoveX(x) => ...
}