我目前正在努力学习F#,并使用codingame作为编程测试题的源。
大多数测试题都涉及从stdin读取一些值,例如前十个值将是整数,接下来的五个值将是字符串。
目前,我正在使用这个函数来读取数据,但感觉它非常不符合F#的风格。
let N = 5
let Reader i =
Console.In.ReadLine()
let words = [0..N-1] |> Seq.map Reader
我目前正在努力学习F#,并使用codingame作为编程测试题的源。
大多数测试题都涉及从stdin读取一些值,例如前十个值将是整数,接下来的五个值将是字符串。
目前,我正在使用这个函数来读取数据,但感觉它非常不符合F#的风格。
let N = 5
let Reader i =
Console.In.ReadLine()
let words = [0..N-1] |> Seq.map Reader
从评论中可以看出,您希望找到最符合“F#原生”(我们称之为“惯用F#”)的从控制台读取输入的方法。
您现在的写法已经足够符合惯用方式了,除了函数通常按照惯例以小写字符开头:
let reader i = Console.ReadLine()
let reader _ = Console.ReadLine()
let words = [0..N-1] |> Seq.map (fun _ -> Console.ReadLine())
1..N
而不是0..N-1
。看起来更清晰。let N = 5
let words = [for _ in 1..N -> Console.ReadLine()]
stdin
值,可以在此处用作快捷方式:stdin.ReadLine()
。还有一个stdout.WriteLine()
。这些操作的好处之一是您甚至不需要打开System
。 - TheQuickBrownFoxopen 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)
let words = [for _ in 1...N -> Console.ReadLine()]
或类似的代码(根据不同的游戏)。但我同意@MarkSeemann的观点:问题描述不够清晰。 - Fyodor Soikinread
来代替Reader
。 - TheQuickBrownFox