You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Mar 27, 2025. It is now read-only.
An Intersection Type is created using the & operator on two types
For example, using some types S and T:
typeS// Some type StypeT// Some type TtypeST=S&T// Intersection Type ST which has all the members of both S & T
From the docs:
& is commutative: A & B is the same type as B & A
Intersection Types - Example
A simple example:
traitGrowable:defgrowBy(percent: Int):this.type=
println(s"Growing by $percent%")
thistraitPaintable:defpaint(color: Int):this.type=
println(s"Painted with color $color")
thisdefresizeAndPaint(obj: Growable&Paintable):Unit=
obj.growBy(20).paint(0x10FF00).growBy(40).paint(0x0010FF)
and using it:
scala> resizeAndPaint(newGrowablewithPaintable)
Growing by 20%Paintedwith color 1113856Growing by 40%Paintedwith color 4351
Union Types
A Union Type is created using the | operator on two types
For example, using some types S and T:
typeS// Some type StypeT// Some type TtypeST=S|T// Union Type ST
From the docs:
| is commutative: A | B is the same type as B | A
Union and Intersection Types are duals of each other
The least upper bound (lub) of a set of types is the union of these types
Union Types - Example I
A simple example
enumTools:caseHammer(size: Int)
caseScrewdriver(size: Int)
enumToolSupplies:caseNail(size: Int)
caseScrew(size: Int)
defprintIt(t: Tools|ToolSupplies):Unit= t matchcasetool: Tools=> println(s"Got a tool: $tool")
casesupply: ToolSupplies=> println(s"Got a supply: $supply")
and using it:
scala>importTools._importToolSupplies._
scala> printIt(Hammer(6))
Got a tool: Hammer(6)
scala> printIt(Nail(9))
Got a supply: Nail(9)
Union Types - Example II
Akka Typed Actors - encoding
The behaviour of an Actor is implemented via the akka.actor.typed.Behavior API
The Behavior takes a type parameter which corresponds to the message types the Behavior can and will handle as formally defined in its Command protocol
On top of the commands an Actor can process, it will also have to process Responses from other Actors as defined in the latter's Response protocol
How do we encode a behaviour so that it can process both commands and responses internally, while limiting the external protocol to Command?
Union Types - Example II
Akka Typed Actors - encoding
Let's look at an example with two Actors: a PingPong Actor and a Pinger Actor:
Union Types - Example II
Akka Typed Actors - encoding
The protocols for the Pinger and the PingPong Actors
The problem to solve is how to extend the Pinger's behaviour so that it "understands" the Pong response
Union Types - Example II
Akka Typed Actors - encoding
Akka Typed 2.6 uses a message adapter/response wrapper approach
The Pong message is wrapped in a WrappedPongResponse message
Union Types - Example II
Akka Typed Actors - encoding
Union Types - Example II
Akka Typed Actors - encoding
Union Types - Example II
Akka Typed Actors - encoding
Message adapters with Response wrappers solve the issue, but
this is quite convoluted and it adds a lot of boilerplate
requires an extra effort from anyone trying to understand the code
There is a better solution using Scala 3's Union Types!
internalBehavior.treatMsg(Command.Reset)
internalBehavior.treatMsg(Command.Run(5))
internalBehavior.treatMsg(Response.RunFailed("Too much to do"))
internalBehavior.treatMsg(Response.RunFinished)
externalBehavior.treatMsg(Command.Reset)
externalBehavior.treatMsg(Command.Run(110))
externalBehavior.treatMsg(Response.RunFailed("Too much to do")) // Doesn't compile
Summary
In this chapter, we have taken a closer look at two new Types in Scala 3:
Union Types
Intersection Types
Union Types define a type that is a Least Upper Bound on two [possibly unrelated] types
Intersection Types define a type that is a Highest Lower Bound on two types
Using Union Types
In this exercise, we will utilise Union Types to vastly simplify the handling of responses to messages sent by an Akka actor
Make sure you're positioned at exercise "union types"
Follow the exercise instructions provided in the README.md file in the code folder