TSet
A TSet[A]
is a mutable set that can participate in transactions in STM.
Create a TSet​
Creating an empty TSet
:
import zio._
import zio.stm._
val emptyTSet: STM[Nothing, TSet[Int]] = TSet.empty[Int]
Or creating a TSet
with specified values:
import zio._
import zio.stm._
val specifiedValuesTSet: STM[Nothing, TSet[Int]] = TSet.make(1, 2, 3)
Alternatively, you can create a TSet
by providing a collection of values:
import zio._
import zio.stm._
val iterableTSet: STM[Nothing, TSet[Int]] = TSet.fromIterable(List(1, 2, 3))
In case there are duplicates provided, the last one is taken.
Put an element to a TSet​
The new element can be added to the set in the following way:
import zio._
import zio.stm._
val putElem: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2)
_ <- tSet.put(3)
} yield tSet).commit
In case the set already contains the element, no modification will happen.
Remove an element from a TSet​
The simplest way to remove an element from TSet
is using delete
method:
import zio._
import zio.stm._
val deleteElem: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3)
_ <- tSet.delete(1)
} yield tSet).commit
Also, it is possible to remove every element that satisfies provided predicate:
import zio._
import zio.stm._
val removedEvenElems: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.removeIf(_ % 2 == 0)
} yield tSet).commit
Or you can keep all the elements that match predicate function:
import zio._
import zio.stm._
val retainedEvenElems: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.retainIf(_ % 2 == 0)
} yield tSet).commit
Note that retainIf
and removeIf
serve the same purpose as filter
and filterNot
. The reason for naming them differently was to emphasize a distinction in their nature. Namely, both retainIf
and removeIf
are destructive - calling them can modify the collection.
Union of a TSet​
Union of the sets A and B represents the set of elements belonging to set A or set B, or both.
Using A union B
method modifies set A
.
import zio._
import zio.stm._
// unionTSet = {1, 2, 3, 4, 5, 6}
val unionTSet: UIO[TSet[Int]] = (for {
tSetA <- TSet.make(1, 2, 3, 4)
tSetB <- TSet.make(3, 4, 5, 6)
_ <- tSetA.union(tSetB)
} yield tSetA).commit
Intersection of a TSet​
The intersection of the sets A and B is the set of elements belonging to both A and B.
Using A intersect B
method modifies set A
.
import zio._
import zio.stm._
// intersectionTSet = {3, 4}
val intersectionTSet: UIO[TSet[Int]] = (for {
tSetA <- TSet.make(1, 2, 3, 4)
tSetB <- TSet.make(3, 4, 5, 6)
_ <- tSetA.intersect(tSetB)
} yield tSetA).commit
Difference of a TSet​
The difference between sets A and B is the set containing elements of set A but not in B.
Using A diff B
method modifies set A
.
import zio._
import zio.stm._
// diffTSet = {1, 2}
val diffTSet: UIO[TSet[Int]] = (for {
tSetA <- TSet.make(1, 2, 3, 4)
tSetB <- TSet.make(3, 4, 5, 6)
_ <- tSetA.diff(tSetB)
} yield tSetA).commit
Transform elements of a TSet​
The transform function A => A
allows computing a new value for every element in the set:
import zio._
import zio.stm._
val transformTSet: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.transform(a => a * a)
} yield tSet).commit
Note that it is possible to shrink a TSet
:
import zio._
import zio.stm._
val shrinkTSet: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.transform(_ => 1)
} yield tSet).commit
Resulting set in example above has only one element.
Note that transform
serves the same purpose as map
. The reason for naming it differently was to emphasize a distinction in its nature. Namely, transform
is destructive - calling it can modify the collection.
The elements can be mapped effectfully via transformSTM
:
import zio._
import zio.stm._
val transformSTMTSet: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.transformSTM(a => STM.succeed(a * a))
} yield tSet).commit
Folds the elements of a TSet
using the specified associative binary operator:
import zio._
import zio.stm._
val foldTSet: UIO[Int] = (for {
tSet <- TSet.make(1, 2, 3, 4)
sum <- tSet.fold(0)(_ + _)
} yield sum).commit
The elements can be folded effectfully via foldSTM
:
import zio._
import zio.stm._
val foldSTMTSet: UIO[Int] = (for {
tSet <- TSet.make(1, 2, 3, 4)
sum <- tSet.foldSTM(0)((acc, el) => STM.succeed(acc + el))
} yield sum).commit
Perform effects for TSet elements​
foreach
is used for performing an STM effect for each element in set:
import zio._
import zio.stm._
val foreachTSet = (for {
tSet <- TSet.make(1, 2, 3, 4)
tQueue <- TQueue.unbounded[Int]
_ <- tSet.foreach(a => tQueue.offer(a).unit)
} yield tSet).commit
Check TSet membership​
Checking whether the element is present in a TSet
:
import zio._
import zio.stm._
val tSetContainsElem: UIO[Boolean] = (for {
tSet <- TSet.make(1, 2, 3, 4)
res <- tSet.contains(3)
} yield res).commit
Convert TSet to a List​
List of set elements can be obtained as follows:
import zio._
import zio.stm._
val tSetToList: UIO[List[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
list <- tSet.toList
} yield list).commit
Size of a TSet​
Set's size can be obtained as follows:
import zio._
import zio.stm._
val tSetSize: UIO[Int] = (for {
tSet <- TSet.make(1, 2, 3, 4)
size <- tSet.size
} yield size).commit