我找不到任何简单的(与try catch
相当简单的方法相比)方法来做到这一点:
try
Some (line.Split delimiter |> Array.map Int32.Parse)
with
|_ -> None
一个不好的(调用Parse
两次)方法是这样的:
let array = line.Split delimiter
let parseSucceed =
array |> Array.exist (Int32.TryParse >> fst >> not)
|> not
if parseSucceed then Some (array |> Array.map Int32.Parse) else None
有没有做这些任务的标准方法?我是否必须编写一个递归函数来处理这个问题?
如果输入不是数组而是流/序列怎么办?
更新:
@Daniel 的方法很棒。
module Seq =
let tryCatch myFun (x: seq<_>) =
let rec loop acc (e: IEnumerator<_>) =
if e.MoveNext() then
match myFun e.Current with
| Some v -> loop (v::acc) e
| None -> (false, acc |> List.rev |> List.toSeq)
else
(true, acc |> List.rev |> List.toSeq)
use e = x.GetEnumerator()
loop [] e
let parse x =
printf "%d " x // log when the function is called.
if x > 3 then None else Some x
let tt myFun x =
let y = Seq.tryCatch myFun x
if fst y then
printfn "yes %A" (y |> snd |> Seq.toArray)
else
printfn "no %A" (y |> snd |> Seq.toArray)
tt parse [| 0;2;1;2;4;1;2 |]
tt parse [| 0;2;1;2 |]
>
0 2 1 2 4 no [|0; 2; 1; 2|] // parse is called minimum number of times
0 2 1 2 yes [|0; 2; 1; 2|]