[F#] .NETライブラリから返される「null値」はどのように扱えばよい?
boxing 機能を用いることで、「null値」と比較できます。box (value) <> nullパターンマッチで判断することもできます。match x.ReadLine() with | null -> None | line -> Some(line).NETライブラリで最終的に null値 を返す関数を扱うときの多相的関数(ジェネリック関数)#light /// Usage: "SeqGivenFuncTillNull<string>(sr.ReadLine)" let SeqGivenFuncTillNull<'a when 'a:not struct> (f:unit->'a) :seq<'a> = seq { let v = ref (f()) in while box (!v) <> null do yield !v do v := f() }StringReader を例にすると、以下のようになります。let str = "testeseテスト!\ndeoweiru!ewp!";; let sr = new StringReader(str);; let lineSeq = SeqGivenFuncTillNull<string>(sr.ReadLine);; let main = for line in lineSeq do printfn "%s" line doneStringReader は TextReader を継承しているので、 TextReader を拡張し、"SeqGivenFuncTillNull"を意識しないようにもできます。/// Extend IO.TextReader. type System.IO.TextReader with member it.to_string_seq = SeqGivenFuncTillNull<string>(it.ReadLine) // Usage: let s = "first line\nsecond line\nthird line\n" let sr2 = new System.IO.StringReader(s) for line in sr2.to_string_seq do // Life is good :) printfn "%s" line;;また、F#で扱いやすいように Option で包むことも可能です。type System.IO.TextReader with member x.TryReadLine() = match x.ReadLine() with | null -> None | line -> Some(line) let SeqGivenFuncTillNull2 (f:unit->'a option) :seq<'a> = seq { let v = ref (f()) while (!v) <> None do yield Option.get (!v) do v := f() }Labels: F# FSharp
0 Comments:
Post a Comment
<< Home