Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Consuming input line-by-line until the end is often useful. In C# I would write the following loop while ((line = Console.ReadLine()) != null) {.

I wanted to do this using "idiomatic" F# (which to me includes avoiding let mutable) and I came up with this:

let rec readlines = seq {
    let line = Console.ReadLine()
    if line <> null then
        yield line
        yield! readlines
}

The last line shows the following warning

Warning FS0040: This and other recursive references to the object(s) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference. This is because you are defining one or more recursive objects, rather than recursive functions. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40'.

The warning would suggest I am actually not writing idiomatic F# (as warnings usually point out problematic code). Is there a better way to write the function that avoids the warnings?

share|improve this question

2 Answers 2

up vote 5 down vote accepted

What you have there is a value, but you probably want it to be a function:

let rec readlines () = seq {
    let line = Console.ReadLine()
    if line <> null then
        yield line
        yield! readlines ()
}
share|improve this answer
    
was this meant to be yield line instead of yield v? There is a pending edit on this post by another user making the change to yield line and I want to make sure before accepting it. –  A Red Herring Jul 10 at 16:59

Mark's response does answer as to the warning you received.

An alternate approach could be

Seq.initInfinite // (1)
    (fun _ -> Console.ReadLine())
|>  Seq.takeWhile (fun line -> line <> null) // (2)

Edit: Could be restructured and more succinct as

 fun _ -> Console.ReadLine()
 |>  Seq.initInfinite // (1)
 |>  Seq.takeWhile ((<>) null) // (2) (3)
  1. Seq.initInfinite<'T> Function (F#)
  2. Seq.takeWhile<'T> Function F#
  3. Partial Application
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.