scalaz/scalaz-stream — pull request #272 by fthomas (2014-11-09 19:11:18+00:00)
Title: Introduce a LengthExceeded exception for text.lines

This PR introduces a special `LengthExceeded` exception for `text.lines` that includes the `String` that caused `lines` to fail. The reason for introducing this exception is that I wanted to have a `lines` that can recover from failures without throwing away information.

Let me give an example where `lines` currently throws away information:
```scala
val p1 = lines(maxLength).onFailure(_ => halt).repeat
```
If `p1` encounters a string `s` that is longer than `maxLength` it will halt, never emit `s`, and repeat the repartitioning into lines. So every input that causes `lines` to throw is lost.

With the `LengthExceeded` exception I can write a never failing process that ensures that it's outputs are always less than or equal to `maxLength`:
```scala
val p2 = lines(maxLength).onFailure {
case LineExceeded(_, s) => emitAll(s.grouped(maxLength).toList)
}.repeat
```
Since the string that caused `lines` to fail is included in the exception I've the chance to emit it in the `onFailure` handler. `p2` will hard wrap inputs that are longer than `maxLength` into chunks of this size.

P.S.: If there is currently a way to create a process similar to `p2`, let me know! I wasn't able to come up with one.