「アクティブパターンなどを追加せずに」と書いたことは知っていますが、とにかくそれらを使用するソリューションを投稿します。これらはこのような問題に最適であり、F# のかなり標準的な機能であるため、回避したい理由はまったくありません。ここでアクティブ パターンを使用すると、コードが確実に読みやすくなります。
(もしあなたが F# の初心者なら、単純な解決策から始めたい理由は理解できますが、とにかく、これは最終的にアクティブ パターンを学習する良い動機になるかもしれません :-)、それらは見た目ほど難しくありません。初見)
文字列が IP アドレスとしてフォーマットされている場合に一致するアクティブなパターンを定義できます (「.」で区切られた 4 つの部分文字列で構成されます)。
let (|IPString|_|) (s:string) =
match s.Split('.') with
| [|a;b;c;d|] -> Some(a, b, c, d) // Returns 'Some' denoting a success
| _ -> None // The pattern failed (string was ill-formed)
match s with
| IPString(a, b, c, d) ->
// Matches if the active pattern 'IPString' succeeds and gives
// us the four parts of the IP address (as strings)
(parseOrParts a, parseOrParts b, parseOrParts c, parseOrParts d)
| _ -> failwith "wrong format"
これは、文字列が正しくない場合に対処できる適切な方法です。もちろん、失敗しないバージョンを定義することもできます (文字列の形式が正しくない場合は、たとえば 0.0.0.0 を返します)。
// This active pattern always succeeds, so it doesn't include the "|_|" part
// in the name. In both branches we return a tuple of four values.
let (|IPString|) (s:string) =
match s.Split('.') with
| [|a;b;c;d|] -> (a, b, c, d)
| _ -> ("0", "0", "0", "0")
let (IPString(a, b, c, d)) = str
(parseOrParts a, parseOrParts b, parseOrParts c, parseOrParts d)
ほとんどの人は、これがより読みやすいことに同意すると思います。もちろん、単一目的のスクリプトのためだけに何か単純なものを書きたい場合は、警告を無視するだけでかまいませんが、より大きなものについては、アクティブなパターンを好みます。