前回の「Haskell で代数的データ型の値を print で出力」では、型のフィールドに型変数が含まれていなかった。今回はフィールドに型変数が含まれる場合について試してみる。
Iremono a 型
例えば、何でも入る「入れ物」を想定し、型変数を一つフィールドに持つ `Iremono a 型’ を定義。
data Iremono a = Iremono a
これを print で出力できるようにしたい。
instance Show Iremono
ここで、次のように Iremono を Show クラスのインスタンスにすると、
instance Show Iremono
次のように怒られる。 (+_+)
`Iremono' is not applied to enough type arguments Expected kind `*', but `Iremono' has kind `* -> *' In the instance declaration for `Show Iremono'
これは kind と言って、型を分類するための概念らしい。 (cf. Kind – HaskellWiki) 詳しくはわからないので横に置いておく。 ^^; QQQ
instance Show (Iremono a)
ところで、Show クラスのインスタンスにしたい対象は Iremono 型ではなくて Iremono a 型。( Iremono は型ではなくて、型コンストラクタ) だから次のように、
instance Show (Iremono a) where show (Iremono x) = "nakami ari" main = print $ Iremono 100
上記は入れ物の中に中身がある場合に「中身あり」と表示させるようにしただけ。
instance Show a => (Iremono a)
しかし、普通 print と言ったら、その中身を表示させたいので、
instance Show (Iremono a) where show (Iremono x) = show x
これでいいのかなと思いきや、また怒られた。 (+_+)
Could not deduce (Show a) from the context (Show (Iremono a)) arising from a use of `show' at functest.hs:4:23-28 Possible fix: add (Show a) to the context of the type signature for `show' In the expression: show x In the definition of `show': show (Iremono x) = show x In the definition for method `show'
deduce とか難しいことが書かれている (@_@;) けれど、ゆっくりとエラーの内容を読むと、show x の式が問題なことがわかる。show x の x と言ったら、「入れ物」の `中身’ のこと。これはどんな型でも入れることができるので、show を適用できるかどうかはわからない。だから、次のように `中身’ も Show クラスのインスタンスでないといけないことを示す必要がある。
instance Show a => Show (Iremono a) where show (Iremono x) = show x
全体を示すと、
data Iremono a = Iremono a instance Show a => Show (Iremono a) where show (Iremono x) = show x main = print $ Iremono 100
結果は、
100
deriving
前回教えていただいたように deriving を使うと、instance Show … を書かなくても、
data Iremono a = Iremono a deriving Show main = print $ Iremono 100
結果は、次のように表示される。
Iremono 100
0コメント:
コメントを投稿