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) => ...
}
Related
I've recently picked up the Free Monad pattern using cats in an attempt to create a DSL which can be "simplified" before execution. For example, let's say I create a language for interacting with lists:
sealed trait ListAction[A]
case class ListFilter[A](in: List[A], p: A => Boolean) extends ListAction[List[A]]
case class ListMap[A, B](in: List[A], f: A => B) extends ListAction[List[B]]
type ListProgram[A] = Free[ListAction, A]
Before executing any program built with these actions, I want to optimise it by transforming subsequent filters into a single filter and transforming subsequent maps into a single map in order to avoid iterating over the list multiple times:
// Pseudo code - doesn't compile, just illustrates my intent
def optimise[A](program: ListProgram[A]): ListProgram[A] = {
case ListFilter(ListFilter(in, p1), p2) => optimise(ListFilter(in, { a: A => p1(a) && p2(a) }))
case ListMap(ListMap(in, f1), f2) => optimise(ListMap(in, f2 compose f1))
}
Is this possible using the Free Monad, either by inspecting the last action when adding to the program or by optimising as above? Thanks very much.
Below is the code I've been using to create my programs:
trait ListProgramSyntax[A] {
def program: ListProgram[List[A]]
def listFilter(p: A => Boolean): ListProgram[List[A]] = {
program.flatMap { list: List[A] =>
Free.liftF[ListAction, List[A]](ListFilter(list, p))
}
}
def listMap[B](f: A => B): ListProgram[List[B]] = program.flatMap { list =>
Free.liftF(ListMap(list, f))
}
}
implicit def syntaxFromList[A](list: List[A]): ListProgramSyntax[A] = {
new ListProgramSyntax[A] {
override def program: ListProgram[List[A]] = Free.pure(list)
}
}
implicit def syntaxFromProgram[A](existingProgram: ListProgram[List[A]]): ListProgramSyntax[A] = {
new ListProgramSyntax[A] {
override def program: ListProgram[List[A]] = existingProgram
}
}
For example:
val program = (1 to 5).toList
.listMap(_ + 1)
.listMap(_ + 1)
.listFilter(_ % 3 == 0)
EDIT: After my colleague searched for "Free Monad optimize" using the American spelling we found a good answer to this question asserting it is not possible to do this before interpretation.
However, it must surely be possible to interpret the program to produce an optimised version of it and then interpret that to retrieve our List[A]?
I've managed to get what I want by just defining my "program" structure in a recursive ADT:
sealed trait ListAction[A]
case class ListPure[A](list: List[A]) extends ListAction[A]
case class ListFilter[A](previous: ListAction[A], p: A => Boolean) extends ListAction[A]
case class ListMap[A, B](previous: ListAction[A], f: A => B) extends ListAction[B]
trait ListActionSyntax[A] {
def previousAction: ListAction[A]
def listFilter(p: A => Boolean): ListFilter[A] = ListFilter(previousAction, p)
def listMap[B](f: A => B): ListMap[A, B] = ListMap(previousAction, f)
}
implicit def syntaxFromList[A](list: List[A]): ListActionSyntax[A] = {
new ListActionSyntax[A] {
override def previousAction: ListAction[A] = ListPure(list)
}
}
implicit def syntaxFromProgram[A](existingProgram: ListAction[A]): ListActionSyntax[A] = {
new ListActionSyntax[A] {
override def previousAction: ListAction[A] = existingProgram
}
}
def optimiseListAction[A](action: ListAction[A]): ListAction[A] = {
def trampolinedOptimise[A](action: ListAction[A]): Eval[ListAction[A]] = {
action match {
case ListFilter(ListFilter(previous, p1), p2) =>
Eval.later {
ListFilter(previous, { e: A => p1(e) && p2(e) })
}.flatMap(trampolinedOptimise(_))
case ListMap(ListMap(previous, f1), f2) =>
Eval.later {
ListMap(previous, f2 compose f1)
}.flatMap(trampolinedOptimise(_))
case ListFilter(previous, p) =>
Eval.defer(trampolinedOptimise(previous)).map { optimisedPrevious =>
ListFilter(optimisedPrevious, p)
}
case ListMap(previous, f) =>
Eval.defer(trampolinedOptimise(previous)).map { optimisedPrevious =>
ListMap(optimisedPrevious, f)
}
case pure: ListPure[A] => Eval.now(pure)
}
}
trampolinedOptimise(action).value
}
def executeListAction[A](action: ListAction[A]): List[A] = {
def trampolinedExecute[A](action: ListAction[A]): Eval[List[A]] = {
action match {
case ListPure(list) =>
Eval.now(list)
case ListMap(previous, f) =>
Eval.defer(trampolinedExecute(previous)).map { list =>
list.map(f)
}
case ListFilter(previous, p) =>
Eval.defer(trampolinedExecute(previous)).map { list =>
list.filter(p)
}
}
}
trampolinedExecute(action).value
}
This has the downside that I don't get stack-safety for free and have to ensure my optimisation and execution methods are properly trampolined.
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
I'm trying to implement a container for a match (like in sports) result so that I can create matches between the winners of other matches. This concept is close to what a future monads is as it contains a to be defined value, and also close to a state monad as it hides state change. Being mostly a begginer on the topic I have implemented an initial version in scala that is surely improvable. I added a get method that I'm not sure was a good idea, and so far the only way to create a value would be Unknown(null) which is not as elegant as I'd hoped. What do you think I could do to improve this design?
case class Unknown[T](t : T) {
private var value : Option[T] = Option(t)
private var applicatives: List[T => Unit] = Nil
def set(t: T) {
if (known) {
value = Option(t)
applicatives.foreach(f => f(t))
applicatives = Nil
} else {
throw new IllegalStateException
}
}
def get : T = value.get
def apply(f: T => Unit) = value match {
case Some(x) => f(x);
case None => applicatives ::= f
}
def known = value == None
}
UPDATE: a usage example of the current implementation follows
case class Match(val home: Unknown[Team], val visit: Unknown[Team], val result: Unknown[(Int, Int)]) {
val winner: Unknown[Team] = Unknown(null)
val loser: Unknown[Team] = Unknown(null)
result.apply(result => {
if (result._1 > result._2) {
home.apply(t => winner.set(t))
visit.apply(t => loser.set(t))
} else {
home.apply(t => loser.set(t))
visit.apply(t => winner.set(t))
}
})
}
And a test snippet:
val definedUnplayedMatch = Match(Unknown(Team("A")), Unknown(Team("B")), Unknown(null));
val definedPlayedMatch = Match(Unknown(Team("D")), Unknown(Team("E")), Unknown((1,0)));
val undefinedUnplayedMatch = Match(Unknown(null), Unknown(null), Unknown(null));
definedUnplayedMatch.winner.apply(undefinedUnplayedMatch.home.set(_))
definedPlayedMatch.winner.apply(undefinedUnplayedMatch.visit.set(_))
undefinedUnplayedMatch.result.set((3,1))
definedUnplayedMatch.result.set((2,4))
undefinedUnplayedMatch.winner.get must be equalTo(Team("B"));
undefinedUnplayedMatch.loser.get must be equalTo(Team("D"));
UPDATE - CURRENT IDEA : I haven't had much time to work on this because my laptop broke down, but I though it would be useful to write the monad I have so far for those who are interested:
sealed abstract class Determine[+A] {
def map[B](f: A => B): Determine[B]
def flatMap[B](f: A => Determine[B]): Determine[B]
def filter(p: A => Boolean): Determine[A]
def foreach(b: A => Unit): Unit
}
final case class Known[+A](value: A) extends Determine[A] {
def map[B](f: A => B): Determine[B] = Known(f(value))
def flatMap[B](f: A => Determine[B]): Determine[B] = f(value)
def filter(p: A => Boolean): Determine[A] = if (p(value)) this else Unknown
def foreach(b: A => Unit): Unit = b(value)
}
final case class TBD[A](definer: () => A) extends Determine[A] {
private var value: A = _
def map[B](f: A => B): Determine[B] = {
def newDefiner(): B = {
f(cachedDefiner())
}
TBD[B](newDefiner)
}
def flatMap[B](f: A => Determine[B]): Determine[B] = {
f(cachedDefiner())
}
def filter(p: A => Boolean): Determine[A] = {
if (p(cachedDefiner()))
this
else
Unknown
}
def foreach(b: A => Unit): Unit = {
b(cachedDefiner())
}
private def cachedDefiner(): A = {
if (value == null)
value = definer()
value
}
}
case object Unknown extends Determine[Nothing] {
def map[B](f: Nothing => B): Determine[B] = this
def flatMap[B](f: Nothing => Determine[B]): Determine[B] = this
def filter(p: Nothing => Boolean): Determine[Nothing] = this
def foreach(b: Nothing => Unit): Unit = {}
}
I got rid of the set & get and now the TBD class receives instead a function that will define provide the value or null if still undefined. This idea works great for the map method, but the rest of the methods have subtle bugs.
For a simple approach, you don't need monads, with partial application is enough:
//some utilities
type Score=(Int,Int)
case class MatchResult[Team](winner:Team,loser:Team)
//assume no ties
def playMatch[Team](home:Team,away:Team)(score:Score)=
if (score._1>score._2) MatchResult(home,away)
else MatchResult(away,home)
//defined played match
val dpm= playMatch("D","E")(1,0)
//defined unplayed match, we'll apply the score later
val dum= playMatch("A","B")_
// a function that takes the dum score and applies it
// to get a defined played match from an undefined one
// still is a partial application of match because we don't have the final result yet
val uumWinner= { score:Score => playMatch (dpm.winner,dum(score).winner) _ }
val uumLoser= { score:Score => playMatch (dpm.loser,dum(score).loser) _}
//apply the scores
uumWinner (2,4)(3,1)
uumLoser (2,4)(0,1)
//scala> uumWinner (2,4)(3,1)
//res6: MatchResult[java.lang.String] = MatchResult(D,B)
//scala> uumLoser (2,4)(0,1)
//res7: MatchResult[java.lang.String] = MatchResult(A,E)
This is a starting point, I'm pretty sure it can be further refined. Maybe there we'll find the elusive monad. But I think an applicative functor will be enough.
I'll give another pass later...
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.