Skip to content

Commit daaf825

Browse files
committed
#7 Add withFilter(), so that for() comprehension could be used
1 parent 1de8a17 commit daaf825

File tree

3 files changed

+76
-7
lines changed

3 files changed

+76
-7
lines changed

README.md

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,12 @@ String received: edef
339339
```
340340

341341
### Scala-specific channel features
342-
Since Scala is a functional language, this implementation of channels supports functors.
342+
Since Scala is a functional language, this implementation of channels supports functional operations used in for comprehension.
343343

344344
#### map()
345345

346+
You can lazy map messages in a channel.
347+
346348
```scala
347349
// Creating a channel of integers
348350
val chInt = Channel.make[Int](2)
@@ -362,24 +364,70 @@ val s2: String = chString.recv()
362364

363365
#### filter()
364366

367+
You can lazy filer messages in a channel.
368+
365369
```scala
366370
// Creating a channel of integers
367-
val ch1 = Channel.make[Int](3)
371+
val chInput = Channel.make[Int](3)
368372

369373
// Filter the original channel
370-
val chFiltered = ch1.filter(v => v != 2)
374+
val chFiltered = chInput.filter(v => v != 2)
371375

372376
// Send some integers
373-
ch1.send(1)
374-
ch1.send(2)
375-
ch1.send(3)
376-
ch1.close()
377+
chInput.send(1)
378+
chInput.send(2)
379+
chInput.send(3)
380+
chInput.close()
377381

378382
// Receive filtered values
379383
val v1 = chFiltered.recv() // 1
380384
val v2 = chFiltered.recv() // 3
381385
```
382386

387+
#### for() comprehension
388+
389+
You can use `for` comprehension for channels.
390+
391+
```scala
392+
// Creating a channel of integers
393+
val chInput = Channel.make[Int](3)
394+
395+
// Applying maps and filters
396+
val chOutput = chInput
397+
.map(v => v * 2)
398+
.filter(v => v != 4)
399+
400+
// Sending values to the input channel
401+
chInput.send(1)
402+
chInput.send(2)
403+
chInput.send(3)
404+
chInput.close()
405+
406+
// Traversing the output channel using for comprehension
407+
for {
408+
a <- chOutput
409+
if a > 5
410+
} println(a)
411+
412+
// Outputs:
413+
// 6
414+
```
415+
416+
#### toList
417+
418+
You can convert a channel to `List` by collecting all messages. This operation will block until the channel is closed.
419+
420+
```scala
421+
val chInput = Channel.make[Int](3)
422+
423+
chInput.send(1)
424+
chInput.send(2)
425+
chInput.send(3)
426+
chInput.close()
427+
428+
val lst = chInput.toList // List(1, 2, 3)
429+
```
430+
383431
## Reference
384432

385433
*ToDo*

src/main/scala/com/github/yruslan/channel/ReadChannel.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ trait ReadChannel[T] extends ChannelLike {
4343

4444
def map[U](f: T => U): ReadChannel[U] = new ChannelDecoratorMap[T, U](this, f)
4545
def filter(f: T => Boolean): ReadChannel[T] = new ChannelDecoratorFilter[T](this, f)
46+
def withFilter(f: T => Boolean): ReadChannel[T] = new ChannelDecoratorFilter[T](this, f)
4647

4748
def toList: List[T] = {
4849
val lst = new ListBuffer[T]

src/test/scala/com/github/yruslan/channel/ChannelSuite.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,26 @@ class ChannelSuite extends AnyWordSpec with BeforeAndAfterAll {
898898

899899
assert(lst == List(2, 6))
900900
}
901+
902+
"test for comprehension" in {
903+
val ch1 = Channel.make[Int](3)
904+
905+
val ch2 = ch1
906+
.map(v => v * 2)
907+
.filter(v => v != 4)
908+
909+
ch1.send(1)
910+
ch1.send(2)
911+
ch1.send(3)
912+
ch1.close()
913+
914+
val outputChannel = for {
915+
a <- ch2
916+
if a > 5
917+
} yield a
918+
919+
assert(outputChannel.recv() == 6)
920+
}
901921
}
902922

903923
"master/worker model" should {

0 commit comments

Comments
 (0)