人気ブログランキング | 話題のタグを見る

Eliza (4) matchSomewhere

eliza.hs の3番目の関数は matchSomewhere だ。定義は次のようになる。

matchSomewhere :: String -> String -> Maybe String
matchSomewhere pat str@(s:rs) = maybe (matchSomewhere pat rs) Just (match pat str)
matchSomewhere _ _ = Nothing

maybe は match の時にも出ていた。第3引き数をテストして、Nothing ならば第1引き数の (matchSomewhere pat rs) が返され、Just a なら、コンテナの a が取り出されて第2引き数の Just を関数適用して、Just a が返される。

Prelude> maybe (Just 1) Just (Just 2)
Just 2
Prelude> maybe (Just 1) Just Nothing
Just 1

matchSomewhere の第1引き数 pat は検索する文字列パターンだ。第2引数の str@(s:rs) はパターンが検索される文字列のパターンだが、@記法で書かれている。(s:rs) と同じものだが、@記法で str を (s:rs) の別名として扱うことができる。

matchSomewhere pat str@(s:rs) = maybe (matchSomewhere pat rs) Just (match pat str)

で pat = "world" str@(s:rs) = "the world" だったとすると、さいしょに右端の (match pat str) が評価される。つまり、match "world" "the world" だから値は Nothing だ。

すると、maybe の第1引き数 matchSomewhere pat rs つまり、matchSomewhere "world" "he world" が評価される。この場合も match pat str は Nothing だから、matchSomewhere "world" "e world" が評価される。

上の場合も match pat str の値がNothingだから ... と展開が進んでいく。これを式の展開で表現すると、

matchSomewere "world" "the world"
= maybe (matchSomewhere "world" "he world") Just (match "world" "the world")
= maybe (matchSomewhere "world" "he world") Just Nothing
= matchSomewhere "world" "he world"
= maybe (matchSomewhere "world" "e world") Just (match "world" "he world")
= maybe (matchSomewere "world" "e world") Just Nothing
= matchSomewhere "world" "e world"
...
= matchSomewhere "world" " world"
...
= matchSomewhere "world" "world"
= maybe (matchSomewhere "world" "orld") Just (match "world" "world")
= maybe (matchSomewhere "world" "orld") Just (Just "")
= Just ""

となって pat = "world" と str@(s:rs) = "the world" が後方一致することが分かる。

matchSomewhere pat str@(s:sr) 関数はパターンの後方一致をテストする関数だった。

これは eliza.hs を load して確認することができる。

Prelude> :load eliza.hs
[1 of 1] Compiling Main ( eliza.hs, interpreted )
Ok, modules loaded: Main.
*Main> matchSomewhere "world" "the world"
Just ""
*Main> matchSomewhere "worl" "the world"
Nothing
by tnomura9 | 2012-07-19 22:37 | Haskell | Comments(0)
<< Eliza (5) apply... Eliza (3) match >>