重复附加到列表,直到抛出异常

时间:2017-12-17 07:11:37

标签: .net f# functional-programming

我需要创建一个只在抛出异常时停止的泛型函数。在下面的示例中,我需要创建一个正数列表:通过创建一个mutable列表然后无限地附加到它。

我需要使用异常来打破循环,如何停止使用可变列表来保存结果但实现相同的功能?

let many f =
    let mutable list = []

    let rec many' () =
        list <- list @ f()
        many'()

    try many'() with Failure _ -> ()
    list

let mutable n = Console.ReadLine() |> Int32.Parse

let positiveNumbers = many (fun () ->
                               n <- n - 1
                               if n < 0 then failwith ""
                               else n)

1 个答案:

答案 0 :(得分:2)

您可以将异常处理移动到循环中。

let many f =
    let rec loop list =
        try loop <| f() :: list
        with Failure _ -> List.rev list
    loop List.empty

let positiveNumbers = 
    many (fun () ->
        let n = Console.ReadLine() |> Int32.Parse
        if n > 0 then n
        else failwith "")

但是,你不应该为(预期的)程序流程使用例外。您可以通过引入predicate来完成您的工作。

let many f predicate =
    let rec loop list =
        let n = f()
        if predicate n then
            loop <| n :: list
        else
            List.rev list
    loop List.empty

let positiveNumbers = 
    many (fun () -> Console.ReadLine() |> Int32.Parse) 
         (fun n  -> n > 0)

包装 - 使用Option类型进行(扩展)验证。

let many f =
    let rec loop list =
        match f() with
        | Some n
            -> loop <| n :: list
        | _ -> List.rev list
    loop List.empty

let f() =
    match Console.ReadLine() |> Int32.TryParse with
    | true, i 
        -> if i > 0 then Some(i) else None
    | _ -> None

let positiveNumbers = many f