Hatena::Grouphaskell

lnzntのHaskell日記 このページをアンテナに追加 RSSフィード

2014年11月24日(月)

型クラス

| 19:09 |  型クラス - lnzntのHaskell日記 を含むブックマーク はてなブックマーク -  型クラス - lnzntのHaskell日記  型クラス - lnzntのHaskell日記 のブックマークコメント

型と型クラス。自分には難解です。

とりあえず、参考書籍見ながら勉強したことをメモしておく。

----

型クラス

型クラスは型のクラス

多相性に制約を付けられる。制約を付けられた多相性をアドホック多相と呼ぶ。それに対して、制約のない多相性をパラメータ多相と呼ぶ。

以下は例。

sort :: (Ord a) => [a] -> [a]

「(Ord a) =>」が「a は Ord クラスの制約を満たす型」という制約を示す。この時、型 a は Ord クラスインスタンスでなければならない。

クラスメソッド

Eq クラスの (==)、(/=)関数のように、そのクラスを特徴付ける関数をクラスメソッドと呼ぶ。Eq クラスインスタンスの型の値はすべてそのクラスメソッドの引数にできる。

クラスメソッドインスタンスごとに異なる実装でもよい。(多重定義(overloading))

class 宣言

class 宣言の例

class Eq a where
  (==), (/=) :: a -> a -> Bool

  x == y = not (x /= y)  -- (==)クラスメソッドのデフォルトの実装
  x /= y = not (x == y)  -- (/=)クラスメソッドのデフォルトの実装

継承を含む class 宣言の例は以下。

class (Eq a) = > Ord a where
    compare     :: a -> a -> Ordering
      :

「(Eq a) =>」がスーパークラスの指定。Ord が Eq のサブクラスである。


instance 宣言 と deriving 宣言

インスタンスであることを宣言するには instance 宣言を使う。

deriving 宣言は instance 宣言の簡易な方法だが、使えるクラスが「Eq」「Ord」などに限られる。

deriving 宣言の例

data A = A String String deriving Show

aElement = A "http://localhost/" "myComputer"

main = do
    print $ aElement   -- 「A "http://localhost/" "myComputer"」と表示される
data A =data A = A { aUri :: String, aLabel :: String } deriving Show

aElement = A "http://localhost/" "myComputer"

main = do
    print $ aElement
    -- 「A {aUri = "http://localhost/", aLabel = "myComputer"}」と表示される。

instance 宣言の例

data A = A String String

instance Show A where
    show (A uri label) = "<a href=\"" ++ uri ++ "\">" ++ label ++ "</a>"

aElement = A "http://localhost/" "myComputer"

main = do
    print $ aElement
    -- 「<a href="http://localhost/">myComputer</a>」と表示される。

show は Show クラスクラスメソッド。オーバロードしている、という解釈でいいのかな。スーパクラスのデフォルト実装を上書きしているのでオーバライドのような感覚だけど、異なる型での関数適用を別途に定義しているのでオーバロードかなあ。よくわからない。

この例で (data A ... の行で) deriving 宣言を併用すると、コンパイル時に「Duplicate instance declarations:」エラーになる。