2012年 12月 14日
さて、ファイルへの出力が分かったので、何か役立ちそうなテキストファイルを出力してみよう。
ということで、Unicode表を作ってみよう。
ユニコード漢字全文字を作るのは、ユニコード全20902字で説明したが、プログラムを再掲しよう。
import Data.Char
import Data.List
fromK :: Char -> [Char]
fromK c = c : fromK (chr ((ord c) + 1))
unicode = take 20902 (fromK '一')
こでで、unicode を評価すれば、長さが20902の文字列ができあがる。
これをそのままファイルとして出力するには、
*Main Data.List> writeFile "unicodetest.txt" unicode
だけで良いのだが、これでは、1行に20902文字並んだとんでもないファイルができるだけだ。
一定の間隔で改行を入れないと表示のときにこまるので、一定間隔でこの長い文字列(リスト)を切ろう。
リストを2つに分ける関数 splitAtがある。切る位置と、元のリストを与えれば、2つに分けてくれる。
*Main Data.List> :t splitAt
splitAt :: Int -> [a] -> ([a], [a])
さて、これを使って、一定間隔でリストを切る関数を作ってみた。
splitEvery :: Int -> [a] -> [[a]]
splitEvery n s
| null sx = [fx]
| otherwise = fx : (splitEvery n sx)
where (fx,sx) = splitAt n s
動作確認すると、こんな感じ。
*Main Data.List> splitEvery 5 [1..16]
[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16]]
これで、長大な文字列を32文字毎に切った文字列のリストができる。
unicode = splitEvery 32 (take 20902 (fromK '一'))
次に、各32文字長の文字列を改行を挟みながら1つの文字列にしてしまおう。
改行で区切る関数がlinesなのだが、その逆の改行を挟みながらくっつける関数はunlineである。
unicodetable = unlines unicode
これで、32文字毎に改行したものが得られた。
*Main Data.List> putStrLn (take 100 unicodetable)
一丁丂七丄丅?万丈三上下丌不与?丐丑丒?且丕世丗丘丙????丞丟
?両?丣两?並?丨?个丫?中丮丯丰丱串??丵丶?丸丹?主丼??丿
乀乁乂乃乄久?乇???之?乍乎乏?乑???乕乖乗乘乙乚?乜九乞也
?
*Main Data.List>
これをファイルに書き出せば、ユニコード表の完成である。
しかし、これでは、コードの対応を取り難い。
各行の最初に、文字コードを入れてみよう。
unicodetable = unlines (map addhead unicode)
addhead xa@(x:_) = show (ord x) ++ " " ++ xa
文字列の先頭に、先頭文字のコードを入れてみた。
これで、もう一度プログラムを読み込んで実行していみよう。
*Main Data.List> putStrLn (take 100 unicodetable)
*Main Data.List> putStrLn (take 100 unicodetable)
19968 一丁丂七丄丅?万丈三上下丌不与?丐丑丒?且丕世丗丘丙????丞丟
20000 ?両?丣两?並?丨?个丫?中丮丯丰丱串??丵丶?丸丹?主丼??丿
20032 乀乁乂乃乄久?乇???之?
先頭の文字コードが10進数のままだと分かりにくい。
ここは16進数に直してみよう。
だが、長くなったので、つづく。