SSブログ

パターンマッチにガード条件を加える [OCaml]

これまでの words の実装ではストリームから Stream.peek で取得した 'a option のヴァリアント型に Some c | None のパターンマッチをして、Some の場合さらにその中身が空白か否かを if を使って条件分岐していた。

「ふつうの Haskell」を読むと Haskell には「ガード」という構文があって、パターンマッチに任意の条件を追加できる。
OCaml にもあるかな?と思って調べたら、あった。以下のように when を使う。

open ExtString.String;;

let stdinstr = Stream.of_channel stdin;;

let words str = 
  let is_space c = String.contains " \t\r\n" c in
  let rec trim_leading charstr =
    match (Stream.peek charstr) with
      Some c when is_space c -> (Stream.junk charstr; trim_leading charstr)
    | Some _ -> charstr
    | None -> charstr
  in
  let rec cut_first_word str =
    let c = Stream.next str in
    match (Stream.peek str) with
      Some next_char when is_space next_char -> c :: []
    | Some next_char -> c :: (cut_first_word str)
    | None -> c :: []
  in
  Stream.from (
    fun i -> 
      try
        let trimmed = trim_leading str in
        Some (implode (cut_first_word trimmed))
      with Stream.Failure -> None
  )
;;

Stream.iter (Printf.printf "[%s] ") (words stdinstr);;

パターンマッチと if で2階層混在していたのがパターンマッチだけになったのでコードが気持ちすっきりする。


nice!(1)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 1

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。