1. 文字列から代数的データ型へ変換したい
Haskell の print 関数で日本語を出力するために、以下のコードを参考にした。
上記には、
「文字列から、代数的データ型へ変換するための、Read クラスの導出インスタンスの使い方」
についても、わかりやすく書かれていた。忘れないうちに、練習しておこう。o(^^)o
2. Show クラスの使い方はわかってきた
ところで、Read の反対 Show クラスについては、少しわかるようになった。
しかし、Read についてはチンプカンプンだった。 (+_+)
3. Read クラスについて
文字列を、特定の型へ変換する例を、最初に書いたのは以下の記事。
この記事を書いたときは、まだ、
「返り値の型を指定する関数」
について理解してなかった。そういう書き方をするものだ、と疑問を持たずに写経。
後になって、腑に落ちなかったので、少し調べた。
read 関数の基本
基本となる要点を復習しておく。
例えば、文字列 “100” を読み込んで、数値 200 と足し合わせる場合、
*Main> (read "100" :: Int) + 200 300
read 関数の返り値の型を Int と指定する必要がある。
read の関数の型は、
(Prelude より)
read 関数の、型変数 a は Read クラスのインスタンスだという制約がある。
Int 型は Read クラスのインスタンスとなので、返り値を Int で型付けてもエラーとならない。
上記では、返り値を Int と型を指定した。
別の書き方として、read 関数の型を指定することもできる。
*Main> (read :: String -> Int) "100" + 200 300
型推論が行われる場合、型を明示的に書く必要はない
ただし、この場合 + 200 と文脈があるので型推論が行われ、
*Main> read "100" + 200 300
のように返り値の型を明示的に指定しなくても大丈夫。
実装について
ちなみに実装は、GHC.Read モジュールの中で instance Read Char と定義されていた。
Read, Show のドキュメントを読んでも理解できなかった
しかし、これだけでは The Haskell 98 Language Report の
を読んでも相変わらず理解できず… (@_@;)
4. Read クラスの導出インスタンスを使う
そこで最初に参考にしたコードを真似て、Read の導出インスタンスを使う方法を試してみる。データは、前回と同じく Person 型の値とする。
以下の内容で UTF-8 で保存。(person.txt)
Person {name = "太郎", age = 20} Person {name = "次郎", age = 30}
フィールドラベルで値を構築
その前に、「フィールドラベルを使って値を構築できるんだっけ?」と疑問を感じたので、調べたら、
ラベルの付いたフィールドをもつ構築子は構成要素が位置ではなく名前で 指定される値を構成するのに使用できる。宣言リストで用いるブレースとは 違い、これらはレイアウトの支配を受けない。
知らなかった。 ^^;
導出インスタンスを使って定義
一行ごとに、文字列から Person 型へと変換を行うことにする。person.hs の記述は、以下の通り。
import qualified System.IO.UTF8 as U data Person = Person {name :: String, age :: Int} deriving (Read) instance Show Person where show (Person name age) = name ++ " " ++ show age main = U.getContents >>= U.print . map (read :: String -> Person) . lines
コマンドラインより、
runghc person.hs < person.txt > result.txt
結果は、
[太郎 20,次郎 30]
次は自前で実装する方法を調べよう~。 CCC
追記(2011.11.26) : コンマ区切りのデータを、一度タプルに変換した後、特定の型へ変換する方法は、以下を参照。
- Haskell の mapM_ – foldr と (>>) を意識して の「ファイルからデータを読み込む」
0コメント:
コメントを投稿