2017-12-17 7 views
2

예외를 throw 할 때만 중지되는 일반 함수를 만들어야합니다. 다음 예제에서는 양수 숫자 목록을 만들 필요가 있습니다. mutable 목록을 만들어 무한히 추가합니다.예외를 throw 할 때까지 목록에 추가 반복하기

루프를 끊기 위해 예외를 사용해야합니다. 변경 가능한 목록을 사용하여 결과를 저장하지 만 어떻게 동일한 기능을 수행 할 수 있습니까?

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

여기에서 '변경 가능'하지 않아도됩니다. –

+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 유형을 --using.

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