List.fill(n)(buyCoffee(cc)) an interesting thing is done; the signature of List.fill is override def fill[A](n: Int)(elem: => A): CC[A], this has two important syntactic things in it:
override def fill[A](n: Int)(elem: => A): CC[A] = {
val b = newBuilder[A]
b.sizeHint(n)
var i = 0
while (i < n) {
b += elem // lazily evaluated, so will call buyCoffee() n times
i += 1
}
b.result()
}
val x = new StringBuilder("Hi")
val y = x.append("Hi")
val r1 = y.toString() // -> HiHi
val r2 = y.toString() // -> HiHi
y with the value of the RHS of the expression (x.append("Hi")), r2 would evaluate to “HiHiHi”, thus this is not referentially transparent; StringBuilder.append is not a pure function