Open2
『Haskellによるプログラミングの思考法』のメモ
pdf版が出てるのを知ったので、買ってしまった。
オーム社から出ている『関数プログラミング入門』を書き直したもののようだ。Main.hs
の1行目が赤で表示されるが、とりあえず動くのでそのまま。
実行方法のメモ。プロジェクトのルートで以下のコマンドを実行。
$ stack build
$ stack run
または
$ stack ghci
> main
例題: 頻出単語
以前、Haskellを本で勉強したときはファイルから読んだり、書き込んだりして、直接Haskell使って何かしたということがなかった反省があるので、ただ写経するのではなく、実際に文章の頻出単語を計算してみる。
module CommonWords where
import Data.Char (toLower, GeneralCategory (LowercaseLetter))
import Data.List (sort, sortBy)
import Data.Ord (comparing)
import Text.Printf (printf)
import System.IO (IOMode(ReadMode), hGetContents, openFile, hClose)
sortWords :: [String] -> [String]
sortWords = sort
countRuns :: [String] -> [(Int, String)]
countRuns [] = []
countRuns (x:xs) = (length q + 1, x) : countRuns p
where
q = [a | a <- xs, a == x]
p = [a | a <- xs, a /= x]
sortRuns :: [(Int, String)] -> [(Int, String)]
sortRuns = (sortBy . flip) (comparing fst)
showRun :: (Int, String) -> String
showRun (i, x) = printf "%s %d\n" x i
commonWords :: Int -> String -> String
commonWords n = concat . map showRun .take n . sortRuns . countRuns . sortWords . words . map toLower
printCommonWords :: Int -> FilePath -> IO ()
printCommonWords n filename = do
handle <- openFile filename ReadMode
contents <- hGetContents handle
putStr (commonWords n contents)
hClose handle
ここで、ちょうどPythonで同じことをしているコードがあるので比較してみる。
リンク先のコードは、大文字小文字を区別しているのでdata = data.lower()
のコメントアウトを外す。
文字カウントするテキストを落とす。
curl -OL https://www.gutenberg.org/cache/epub/8868/pg8868.txt
計算してみると、どちらも一致する。Pythonが一瞬で終わるのに対して、Haskell版はビルドしても計算に時間かかる。コードの方は、Haskellのほうが読みやすい。PythonでもHaskellっぽくも書けますよという人がいるかも知れない。
2730 the
1661 i
1454 to
1296 and
1250 of