4

I want to write a function to abstract Console.ReadLine() into a string seq

the seq should break when line = null

ConsoleLines(): unit -> string seq

To be used like this:

for line in ConsoleLines() do
    DoSomething line

How do you write this function?

Thanks

Luca Martinetti
  • 3,396
  • 6
  • 34
  • 49

5 Answers5

6
Seq.initInfinite (fun _ -> Console.ReadLine())
thr
  • 19,160
  • 23
  • 93
  • 130
5

Its not overly pretty, but it works as expected:

let rec ConsoleLines() =
    seq {
        match Console.ReadLine() with
        | "" -> yield! Seq.empty
        | x -> yield x; yield! ConsoleLines()
    }
Juliet
  • 80,494
  • 45
  • 196
  • 228
4
let ConsoleLines =
    seq {
        let finished = ref false
        while not !finished do
            let s = System.Console.ReadLine()
            if s <> null then
                yield s
            else
                finished := true
    }

(Note that you must use ref/!/:= to do mutable state inside a sequence expression.)

Brian
  • 117,631
  • 17
  • 236
  • 300
3

Slightly different:

let readLines (sr:TextReader) =
    Seq.initInfinite (fun _ -> sr.ReadLine())
    |> Seq.takeWhile (fun x -> x <> null)

let consoleLines() =
    readLines Console.In
Nathan Howell
  • 4,627
  • 1
  • 22
  • 30
2
let consoleLines = Seq.takeWhile ((<>) "") (seq { while (true) do yield System.Console.ReadLine() })
Simon Buchan
  • 12,707
  • 2
  • 48
  • 55