HaskellでN-gram
N-gramって知ってますか?
任意の文字列に対して、N=2のとき
"hello" => "he", "el", "ll", "lo"
という文字列を生成するものです
これをHaskellで実装するにはどうしたらいいんだろうと考えていました
Stringをtakeでとって...?再帰っぽい??いちいち判定するの??とか考えていましたが、うまく値が取れず悩んでいました
Hoogleで適した関数を探していたのですが、最終手段Google先生に聞いてみました
その回答がこちら
http://codereview.stackexchange.com/questions/70023/function-to-get-ngrams-fast-in-haskell
ngrams :: Int -> [a] -> [[a]] ngrams n l = take (length l - (n - 1)) . map (take n) . tails $ l
目から鱗でした。めっちゃHaskellっぽい!
Data.Listのtails関数はリストが空になるまでtailを適用する関数
先ほどの例と同じで入力が"hello"だとすると
["hello","ello","llo","lo","o",""]
という値を得られます
map (take n)
ですべての要素に対してtakeでn文字取得します
["he","el","ll","lo","o",""]
そして、take (length l - (n - 1))
でn文字部分の要素を返しています
["he","el","ll","lo"]
勉強になりました