I'm learning F#, starting with baby steps. Is there a way to write this code in a more succint way, while keeping the same semantics? Maybe by using a Seq or something like that?

let rec repeatingPrompt predicate (message:string) =
    let value = Console.ReadLine()
    if predicate value then
        repeatingPrompt predicate message
  • \$\begingroup\$ Hi, welcome to Code Review! I hope you receive great answers! \$\endgroup\$
    – Tunaki
    Commented Apr 13, 2016 at 16:04

2 Answers 2


You can use Seq.initInfinite and Seq.find to do this, though I'm not sure it's actually better:

let repeatingPrompt predicate (message:string) =
    let prompt _ =

    Seq.initInfinite prompt |> Seq.find predicate
  • \$\begingroup\$ thank you. Why do you think it is not so useful to do this? Would you have done something along the lines of what I wrote? \$\endgroup\$
    – Grubl3r
    Commented Apr 13, 2016 at 20:35
  • 1
    \$\begingroup\$ @Grubl3r Possibly. Both versions are about the same length, but the Seq version is harder to understand, since you need to know what initInfinite and find do. \$\endgroup\$
    – svick
    Commented Apr 13, 2016 at 21:35

I like svick's answer but wanted to show an alternate way without using Seq module.
It's not very different of yours (not really an improvement), but functional programming tend to favor pattern matching over if tests so maybe it's more "idiomatic".

I also replaced the use of Console with the already available (without opening System) stdin and stdout but that's anecdotic

let rec repeatingPrompt predicate message =
  stdout.WriteLine (message: string) // you can put the type here too

  match stdin.ReadLine () with
  | value when predicate value -> value
  | _ -> repeatingPrompt predicate message

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.