Seq.unfold の使い方がちょっと理解できたのでメモ。
今回 unfold を利用したのは、ある文字列 str から Regex でマッチした部分文字列とその前にある(前のマッチ以降の)部分文字列をペアにして seq として返すというもの。
例を挙げると、文字列 ab1cde23fg45h6ijk に対し、正規表現 \d+ で次のような文字列ペアのシーケンスを取得します。
[("ab", "1"); ("cde", "23"); ("fg", "45"); ("h", "6"); ("ijk", "")]
(実際には list ではなく seq ですが)
let str = "..." // 対象の文字列
let re = new Regex(@"...") // 対象文字列の特定の部分文字列にマッチする正規表現
Seq.unfold
(fun (p : int, m : Match) ->
if p < 0 then None
else if m.Success then
let v = (str.Substring(p, m.Index - p), m.Value)
Some(v, (m.Index + m.Length, m.NextMatch()))
else
let v = (str.Substring(p), "")
Some(v, (-1, m)))
(0, re.Match(str))
ちなみに、Seq.unfold を使う前は次のように再帰を使って書いてました。
let str = "..."
let re = new Regex(@"...")
let rec f1 (p : int) (m : Match) pairs =
if m.Success then
let v = (str.Substring(p, m.Index - p), m.Value)
f1 (m.Index + m.Length) (m.NextMatch()) (pairs @ [v])
else
let v = (str.Substring(p), "")
pairs @ [v]
f1 0 (re.Match(str)) []