Python の __str__(), Ruby の inspect, Java の toString() に相当するものを実装したいときに、どうすればいいか忘れてしまったら、、、 ^^;
追記(2008.10.9) : 匿名さんに Show を deriving する方法について教えていただいた。
代数的データ型
他のデータ型を当該代数的データ型のコンストラクタで包んだデータを値とする。 …
(例えば
(Cons 1 '(2 3 4))
あるいは1:[2,3,4]
)(代数的データ型 – Wikipedia より)
方法を探す方法
ドキュメントの検索
例えば、「人」を表わす型が次のように定義されているとする。
data Person = Person {name :: String, age :: Int}
Haskell のドキュメントを検索 で print 関数を検索すると、自分で定義した型を Show クラスのインスタンスにして、show 関数を定義すればいいことがわかる。(cf. Haskell の show)、
エラーの内容と GHCi で当りをつける
もしくはお手軽に確認するのであれば、とりあえず print 関数を使うことだけは覚えているなら、
main = print (Person "Tarou" 20)
実行すると、
person.hs:4:7: No instance for (Show Person) arising from a use of `print' at person.hs:4:7-31 Possible fix: add an instance declaration for (Show Person) In the expression: print (Person "Tarou" 20) In the definition of `main': main = print (Person "Tarou" 20)
コマンドラインにおいて ghci 、:t, :i を見ると、(cf. Haskell における関数の型と、部分適用)
Prelude> :t print print :: (Show a) => a -> IO () Prelude> :i print print :: (Show a) => a -> IO () -- Defined in System.IO
print 関数は、Show クラスのインスタンスにのみ適用可能なのがわかる。続いて Show についての情報を表示させると、
Prelude> :i Show class Show a where showsPrec :: Int -> a -> ShowS show :: a -> String showList :: [a] -> ShowS -- Defined in GHC.Show
さすがにドキュメントを検索したときのように、次のような細かなことまではわからないのかな?
Minimal complete definition: showsPrec or show.
(Prelude より)
実装
data Person = Person {name :: String, age :: Int} instance Show Person where show (Person name age) = "Person: " ++ name ++ ", " ++ show age main = print (Person "Tarou" 20)
結果は、
Person: Tarou, 20
パターンマッチでは次のことを忘れずに。
data 宣言で宣言した型のフィールドにアクセスするには、データコンストラクタを使ったパターンマッチを利用します。
(ふつうのHaskellプログラミング , p226)
3コメント:
data Person = Person {name :: String, age :: Int} deriving (Eq,Show)
とかやっておくと自分で書かなくても instance にしてくれますよ。
Show クラスも deriving できたんですか。知りませんでした。ありがとうございます。 φ( ̄  ̄*) メモメモ
「ふつうの Haskell プログラミング」(p243) に「deriving 宣言が使える条件の詳細については Haskell 98 Report を参照してください。」とあったので、いつか見ておかねばと思いつつ、見てなかったのでこれを機に読もうと思ったのですが、自分にとっては書かれていることが難しくて... ^^;
とりあえず、導出インスタンス宣言の条件の 1 に 「C が Eq、Ord、Enum、 Bounded、Show あるいは Read のうちの どれか。 」とあったのでこの辺りを理解しないといけないということですよね。 CCC
( http://www.sampou.org/haskell/report-revised-j/derived.html )
コメントを投稿