I am currently trying to learn F# better and I am using codingame as an source of programming quizzes.
Most of the quizess involves reading some values from stdin, like the first ten values on stdin will be ints, the next five will be strings.
Currently, I am using this function to read the data, but it feels very "un-f#".
let N = 5
let Reader i =
Console.In.ReadLine()
let words = [0..N-1] |> Seq.map Reader
If I had to read given numbers of given types, I would write something like
open System
let read parser =
Seq.initInfinite (fun _ -> Console.ReadLine())
|> Seq.choose (parser >> function true, v -> Some v | _ -> None)
which can then be used
let ints = read Int32.TryParse
let ``ten floats`` = read Double.TryParse |> Seq.take 10
Note that if the seq
is used multiple times, ReadLine()
is called again:
let anInt = ints |> Seq.take 1
printfn "%A" anInt
printfn "%A" anInt // need to input an int again
which can be treated by using e.g. List
or Seq.cache
.
For strings, which never fail, use
let strings = read (fun s -> true, s)
if you have a minimum length requirement:
let potentialPasswords = read (fun s -> s.Length > 10, s)