top page > computer > haskell > web_lecture > for_programmer > kind_class.html
更新日:
文責: 重城良国

種類(* -> *)に対する型クラス

(工事中 70%)

倉庫を表す型クラス

storage.hs

型クラスIntStorageを以下のように定義した。

class IntStorage s where
empty :: s
store :: Int -> s -> s
derive :: s -> Maybe (Int, s)

種類(* -> *)の型に対する型クラスを作ることでより一般化することができる。

class Storage s where
empty :: s a
store :: Ord a => a -> s a -> s a
derive :: s a -> Maybe (a, s a)

クラス関数storeで型変数aにOrdの型クラス制約をつけているのはS.Setを型クラスStorageのインスタンスにするときにS.insertを使うためだ。それ以外ではsをs aにしたこととIntをaにしただけだ。クラス関数の型づけに(s a)という形を使っているので、型sの種類が(* -> *)であることを処理系が判定できる。必要はないがより明示的に示すには言語拡張KindSignaturesを使う。コードの先頭に以下のように書き、

{-# LANGUAGE KindSignatures #-}

クラス宣言の先頭を以下のようにする。

class Storage (s :: * -> *) where
...

いろいろな倉庫型

リストを倉庫にする。

instance Storage [] where
empty = []
store = (:)
derive (x : xs) = Just (x, xs)
derive _ = Nothing

集合(Set)を倉庫にする。

モジュールの先頭に以下を追加する。

import qualified Data.Set as S

インスタンス宣言を書く。

instance Storage S.Set where
empty = S.empty
store = S.insert
derive s
| S.null s = Nothing

| otherwise = Just $ S.deleteFindMin s

キューを倉庫にする。

data Queue a = Queue [a] [a] deriving Show

instance Storage Queue where
empty = Queue [] []
store x (Queue f r) = Queue f (x : r)
derive (Queue [] []) = Nothing
derive (Queue (n : f) r) = Just (n, Queue f r)
derive (Queue _ r) = derive $ Queue (reverse r) []

値を保存

stored :: Storage s => s Char
stored = let
s1 = store 'j' empty
s2 = store 'u' s1
s3 = store 'j' s2
s4 = store 'o' s3 in
s4

値のとりだし

derive2 :: Storage s => s Char -> Maybe [Char]
derivw2 s = case derive s of
Just (x, s') -> case derive s' of
Just (y, s'') -> Just [x, y]
_ -> Nothing
_ -> Nothing

試してみる

% ghci storage.hs
*Main> stored :: [Char]
"ojuj"
*Main> derive2 it
Just "oj"
*Main> stored :: S.Set Char
fromList "jou"
*Main> derive2 it
Just "jo"
*Main> stored :: Queue Char
Queue "" "ojuj"
*Main> derive2 it
Just "ju"

まとめ

*型の型に対してだけでなく(* -> *)型の型に対しても型クラスを定義することができる。(* -> *)型の型の値はコンテナとみなせるので(* -> *)型の型に対する型クラスはコンテナの性質を表現していると考えられる。

「種類(kind)とは」へもどる 「モノイドとは」へ

正当なCSSです! HTML5 Powered with CSS3 / styling, and Semantics