Skip to content

Instantly share code, notes, and snippets.

@htsign
Last active July 8, 2019 02:42
Show Gist options
  • Select an option

  • Save htsign/2bc81467617853f9a02e5022a1442b0e to your computer and use it in GitHub Desktop.

Select an option

Save htsign/2bc81467617853f9a02e5022a1442b0e to your computer and use it in GitHub Desktop.
実験的に Seq<'T> と Async<'T> を混ぜてみた
module IO =
open System.IO
open System.Threading.Tasks
// 普通の unfold
let readLines (reader : TextReader) =
match reader with
| null -> nullArg "reader"
| r -> r |> Seq.unfold (fun r -> match r.ReadLine() with null -> None | s -> Some (s, r))
// asyncReadLines : TextReader -> string seq 用のアクティブパターン
let private (|Complete|Fault|) (task : 'a Task) =
async {
try
let! r = task |> Async.AwaitTask
return Complete r
with ex -> return Fault ex // エラー発生のケースは未テスト
} |> Async.RunSynchronously
// Task<'T> を混ぜてみたパターン
let asyncReadLines (reader : TextReader) =
match reader with
| null -> nullArg "reader"
| r -> r |> Seq.unfold (fun r ->
// (|Complete|Fault|) を利用して Task を即実行、成功の可否で分岐させる
match r.ReadLineAsync() with
| Fault _ -> None
| Complete s -> if isNull s then None else Some (s, r))
IO.asyncReadLines stdin
|> Seq.iter (printfn "%s")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment