-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWc.scala
37 lines (32 loc) · 1.05 KB
/
Wc.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package de.codecentric.applicative
import cats.data.{Const, Nested, State, Tuple2K}
import cats.instances.int._
import de.codecentric.applicative.Utils._
import mouse.boolean._
trait Wc {
def run(input: Iterator[Char]): (Int, Int, Int) = {
def countChars[A](c: Char): Const[Int, A] = Const.of(1)
def countLines[A](c: Char): Const[Int, A] = (c == '\n') ?? Const.of[A](1)
//snippet:count-words-state
def countWords[A](c: Char): Nested[State[Boolean, ?], Const[Int, ?], A] =
Nested {
for {
before <- State.get[Boolean]
after = !c.isWhitespace
_ <- State.set[Boolean](after)
} yield {
(!before && after) ?? Const.of[A](1)
}
}
//end
val Tuple2K(Tuple2K(chars_, lines), words_) =
//snippet:count-words-applicative
input.traverse_ { c =>
Tuple2K(Tuple2K(countChars[Unit](c), countLines[Unit](c)),
countWords[Unit](c))
}
//end
(lines.getConst, words_.value.runA(false).value.getConst, chars_.getConst)
}
}
object Wc extends Wc