wvogel日記

自分用の技術備忘録が多めです.

instance宣言

今まで実はHaskellにおいてinstance宣言を使ったことが無かったのでどういうものなのかよく知らなかった。
なので調べてみることに。

身近な実例を探すと、リストモナドの定義があった。

instance Monad [] where
  xs >>= f = concatMap f xs
  return x = [x]

型クラスMonadに属する[]は、以下のように定義されている、ということでしょうか。

まだまだ情報が足りないので、instance宣言はどういうときに利用できるのか
ttp://www.haskell.org/haskellwiki/Orphan_instance
このページを読む限り、モジュール内で未定義のものを定義する時に利用できるようです。
イメージ通り。
読み進めると、どうやらモジュールの階層化(それぞれが独立していること)によって恩恵を受けられるよう。
なんとなく分かるけれど、まだinstanceがどのように用いられるのかわからないので理解に至らない。

というわけで、書いてみた。
誤りがあるソースコード

module InstanceTest where

class MyShow a where
  myShow :: a -> String

instance MyShow a => MyShow [a] where
  myShow xs = concatMap myShow xs
instance MyShow Int where
  myShow x = "Integer"
instance MyShow Char where
  myShow x = [x]

これで、

myShow 'a'
myShow "qwerty"

などは動くけれど、Intは渡しても動かない。なぜでしょう
エラーメッセージは

<interactive>:1:1:
    Ambiguous type variable `a0' in the constraints:
      (MyShow a0) arising from a use of `myShow' at <interactive>:1:1-6
      (Num a0) arising from the literal `1234' at <interactive>:1:8-11
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: myShow 1234
    In an equation for `it': it = myShow 1234

まだ型に対する理解が甘いようです。
うーん