从 stdin 读取的最佳方法是什么?
What's the best way to read from stdin?
我目前正在尝试更好地学习 F#,我正在使用 codingame 作为编程测验的来源。
大部分测验涉及从标准输入读取一些值,比如标准输入的前十个值是整数,接下来的五个是字符串。
目前正在使用这个功能读取数据,但是感觉很"un-f#"。
let N = 5
let Reader i =
Console.In.ReadLine()
let words = [0..N-1] |> Seq.map Reader
从评论中可以看出,您最喜欢 "F#-native"(我们称之为 "idiomatic F#")的控制台读取方式。
你所拥有的已经足够惯用了,除了函数,按照惯例,通常以小写字符开头:
let reader i = Console.ReadLine()
此外,由于您没有使用该参数,因此不必为其命名:
let reader _ = Console.ReadLine()
如果函数够小,可以写成inline,匿名:
let words = [0..N-1] |> Seq.map (fun _ -> Console.ReadLine())
此外,由于您实际上并未使用索引,因此可以将列表声明为 1..N
而不是 0..N-1
。看起来干净一点。
最后,F# 提供了非常方便的列表理解,您可以使用它来实现更好的可读性:
let N = 5
let words = [for _ in 1..N -> Console.ReadLine()]
如果我必须读取给定类型的给定数量,我会写类似
的内容
open System
let read parser =
Seq.initInfinite (fun _ -> Console.ReadLine())
|> Seq.choose (parser >> function true, v -> Some v | _ -> None)
然后可以使用
let ints = read Int32.TryParse
let ``ten floats`` = read Double.TryParse |> Seq.take 10
注意,如果多次使用seq
,会再次调用ReadLine()
:
let anInt = ints |> Seq.take 1
printfn "%A" anInt
printfn "%A" anInt // need to input an int again
可以使用例如List
或 Seq.cache
.
对于永不失败的字符串,使用
let strings = read (fun s -> true, s)
如果您有最小长度要求:
let potentialPasswords = read (fun s -> s.Length > 10, s)
我目前正在尝试更好地学习 F#,我正在使用 codingame 作为编程测验的来源。
大部分测验涉及从标准输入读取一些值,比如标准输入的前十个值是整数,接下来的五个是字符串。
目前正在使用这个功能读取数据,但是感觉很"un-f#"。
let N = 5
let Reader i =
Console.In.ReadLine()
let words = [0..N-1] |> Seq.map Reader
从评论中可以看出,您最喜欢 "F#-native"(我们称之为 "idiomatic F#")的控制台读取方式。
你所拥有的已经足够惯用了,除了函数,按照惯例,通常以小写字符开头:
let reader i = Console.ReadLine()
此外,由于您没有使用该参数,因此不必为其命名:
let reader _ = Console.ReadLine()
如果函数够小,可以写成inline,匿名:
let words = [0..N-1] |> Seq.map (fun _ -> Console.ReadLine())
此外,由于您实际上并未使用索引,因此可以将列表声明为 1..N
而不是 0..N-1
。看起来干净一点。
最后,F# 提供了非常方便的列表理解,您可以使用它来实现更好的可读性:
let N = 5
let words = [for _ in 1..N -> Console.ReadLine()]
如果我必须读取给定类型的给定数量,我会写类似
的内容open System
let read parser =
Seq.initInfinite (fun _ -> Console.ReadLine())
|> Seq.choose (parser >> function true, v -> Some v | _ -> None)
然后可以使用
let ints = read Int32.TryParse
let ``ten floats`` = read Double.TryParse |> Seq.take 10
注意,如果多次使用seq
,会再次调用ReadLine()
:
let anInt = ints |> Seq.take 1
printfn "%A" anInt
printfn "%A" anInt // need to input an int again
可以使用例如List
或 Seq.cache
.
对于永不失败的字符串,使用
let strings = read (fun s -> true, s)
如果您有最小长度要求:
let potentialPasswords = read (fun s -> s.Length > 10, s)