Why does function containing Console.ReadLine() not complete?

跟風遠走 提交于 2019-12-23 10:25:51

问题


I am using Visual Studio 2012, and the function that calls Console.ReadLine() will not execute

let inSeq = readlines ()

in this simple program

open System
open System.Collections.Generic
open System.Text
open System.IO
#nowarn "40"

let rec readlines () =
    seq {
        let line = Console.ReadLine()
        if not (line.Equals("")) then
            yield line
            yield! readlines ()
}

[<EntryPoint>]
let main argv = 
    let inSeq = readlines ()

    0

I've been experimenting and researching this, and cannot see what is probably a very simple problem.


回答1:


Sequences in F# are not evaluated immediately, but rather only evaluated as they're enumerated.

This means that your readlines function effectively does nothing until you attempt to use it. By doing something with inSeq, you'll force an evaluation, which in turn will cause it to behave more like you expect.

To see this in action, do something that will enumerate the sequence, such as counting the number of elements:

open System
open System.Collections.Generic
open System.Text
open System.IO
#nowarn "40"

let rec readlines () =
    seq {
        let line = Console.ReadLine()
        if not (line.Equals("")) then
            yield line
            yield! readlines ()
}

[<EntryPoint>]
let main argv = 
    let inSeq = readlines ()

    inSeq 
    |> Seq.length
    |> printfn "%d lines read"

    // This will keep it alive enough to read your output
    Console.ReadKey() |> ignore
    0



回答2:


If you change the sequence to a list in readLines() you don't have to 'activate' the sequence to run the input recursion:

open System
open System.Collections.Generic
open System.Text
open System.IO
#nowarn "40"

let rec readlines () =    
  [let line = Console.ReadLine()
   if not (line.Equals("")) then
     yield line
     yield! readlines ()]

[<EntryPoint>]
let main argv = 
    let inList = readlines ()

    printfn "END"
    Console.ReadLine() |> ignore
    0

An non recursive approach could be something like this:

let readLines _ = 
  List.unfold (fun i -> 
                 let line = Console.ReadLine()
                 match line with
                 | "" -> None
                 | _ -> Some (line, i)) 0


来源:https://stackoverflow.com/questions/39649493/why-does-function-containing-console-readline-not-complete

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!