2017-12-17 6 views
2

例外をスローするときにのみ停止する汎用関数を作成する必要があります。以下の例では、正の数値リストを作成する必要があります。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) 
+0

あなたは私に 'mutable'を使用しないようにヒントを与えることができるmutable'ここ –

+0

@FoggyFinder'使用する必要はありませんか? – MiP

答えて

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 
関連する問題