2016-09-22 35 views
5

我使用Visual Studio 2012,并调用该函数Console.ReadLine()不会在这个简单的程序为什么包含Console.ReadLine()的函数不完整?

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 

我一直在尝试和研究这个执行

let inSeq = readlines()

,并不能看到可能是一个非常简单的问题。

+0

在控制台上是否有一行可以读取函数?它期待输入,并阻塞,直到收到换行。 – Prune

+0

我不太清楚你在问什么。 VS 2012调试器中的执行将不会等待输入,而会下降到程序的最后一行。 – octopusgrabbus

+0

我看到......里德发布了我正在处理的答案,但做得更好。 – Prune

回答

7

F#中的序列不是立即评估的,而是只在枚举时才进行评估。

这意味着您的readlines函数在您尝试使用它之前无效。通过与inSeq做一些事情,你会强制进行评估,这反过来会导致它更像你的预期。

要看到这个动作,做一些事情,将枚举序列,如计算元素的数量:如果您更改顺序的列表中readlines方法(

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 
+1

你的回答解释了我在调试器中看到的很多奇怪的行为。谢谢。 – octopusgrabbus

+1

@octopusgrabbus是的 - 序列是IEnumerable ,并且是“懒惰”。 –

0

)你没有“激活”运行输入递归序列:

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 

的非递归的方法可以是这样的:

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