>  > 18インチジュークF15系ENKEI パフォーマンスライン PF07 ダークシルバー 7.5Jx18Bluearth エース AE50 225/45R18

18インチジュークF15系ENKEI パフォーマンスライン PF07 ダークシルバー 7.5Jx18Bluearth エース AE50 225/45R18

18インチジュークF15系ENKEI パフォーマンスライン PF07 ダークシルバー 【送料無料!】【スタッドレスタイヤ 7.5Jx18Bluearth エース AE50 メルセデスベンツCLK-CLASS208【グレードCLK320/3.2】【208365/208465】【97-02】詳細要確認商品GruppeM-RAM 225/45R18

型クラス(type class)は,データ型をカテゴライズする役割を持つ概念です. 例えば,数値型全般を表す Num という型クラスは,数値型全般を表します. Num 型クラスの インスタンス(instance)は,具体的な数値型である IntDouble などです.

型クラスは,オブジェクト指向プログラミングにおける "クラス" と似通った概念ですが,レイヤが違う話なので注意が必要です. オブジェクト指向プログラミングにおけるクラスはデータ型であり,インスタンスはオブジェクトですが,Haskell における型クラスはデータ型のひとつ上の概念であり,インスタンスがデータ型です.

2. 型クラス制約

型クラスの存在意義がわかる簡単な例題として ,リストの要素の和を求める関数 sum を考えてみましょう.

sum [] = 0
sum (x:xs) = x + sum xs


この関数 sum の型はどのように書くのが適切でしょうか. 次のように書いてしまうと,Int 以外の数値型のリストに sum を適用できなくなってしまいます.

sum :: [Int] -> Int


かといって,次のような型だと,数値以外のリストにも sum を適用できることになってしまい,不適切です.

sum :: [a] -> a


そこで,型クラスを用いることで,数値のリストにのみ sum を適用できるようにすることができます.

sum :: Num a => [a] -> a


この型シグネチャ宣言における => の左辺 Num a は,"型 aNum クラスのインスタンスである" という制約を表します. この制約は,型クラス制約,あるいは文脈(context)と呼ばれます.

複数の制約がある場合には,次の例のように書きます.

f :: (C a, D a, E b) => [a] -> [b] -> [a]




3. 型クラスの定義

等値性が評価可能な型全般を表す型クラス Eq が標準で定義されています. 型クラス Eq は,class 宣言によって次のように定義されています.

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


型クラスには,その型クラス特有の関数である,クラスメソッド(class method)を定義できます. class 宣言には,クラスメソッドの型シグネチャ宣言とデフォルト定義を記述します. なお,デフォルト定義は省略可能です.

Eq クラスは,(==)(/=) という 2 つのクラスメソッドを持ちます. デフォルト定義を見ると,(==)(/=) によって,(/=)(==) によって定義されているため,後述する instance 宣言で少なくとも片方を実装する必要があります.

4. インスタンス宣言

Eq クラスのインスタンスとして,2 次元空間上の点を表す Point 型を考えます. PointEq クラスのインスタンスであることを示すには,instance 宣言を記述します.

data Point = Pt Double Double
instance Eq Point where
 (Pt x y) == (Pt x' y') = x == x' && y == y'
main = do print $ (Pt 1 2) == (Pt 2 3) -- 出力: False
 print $ (Pt 1 2) /= (Pt 2 3) -- 出力: True
 print $ (Pt 1 2) == (Pt 1 2) -- 出力: True




5. クラスの継承

順序付けの可能な型全般を表す型クラス Ord が標準で定義されています.

順序付けの可能な型は,等価性の評価も当然できると考えることができます. これを受けて,Ord クラスは Eq クラスの拡張として,次のように定義されています.

data Eq a => Ord a where
 compare :: a -> a -> Ordering
 (<), (<=), (>), (>=) :: a -> a -> Bool
 max, min :: a -> a -> a
 --(デフォルト実装は省略)
data Ordering = EQ  

エース ダークシルバー AE50 PF07 7.5Jx18Bluearth 225/45R18 ダークシルバー AE50 パフォーマンスライン 18インチジュークF15系ENKEI

| LT | GT

Eq a => Ord a は,Ord クラスのインスタンスは Eq クラスのインスタンスでもなければならないという制約を表します. つまり DUNLOP ダンロップ エナセーブ プレミアム ENASAVE PREMIUM サマータイヤ 215/60R16 阿部商会 MAK VINCI(ヴィンチ) ホイールセット 4本 16インチ 16 X 6.5(VW) +46 5穴 112,Ord クラスのインスタンスは,Eq クラスのクラスメソッド (==), (/=) も実装する必要があります.

型クラス Ord, Eq の関係は,Ord クラスは Eq クラスを継承(inherit)する,とも表現されます. このとき ブリヂストン PLAYZ プレイズ PX-C サマータイヤ 185/65R15 MANARAY EUROSPEED ユーロスピード G10 ホイールセット 4本 15インチ 15 X 5.5 +45 4穴 100,Eq クラスはスーパークラス(superclass),Ord クラスはサブクラス(subclass)と呼ばれます.

複数のクラスを継承(多重継承)する場合,class 宣言は次の例のように記述します.

class (C a, D a) => E a where ...


次のプログラムは ★色番号塗装発送40 ソアラ フロントハーフ【ティーアンドイー】DIGNA 前期 40 SOARER フロント ハ-フ スポイラ-,1 次元空間上の点を表す Point 型を定義したものです.

data Point = Pt Double
instance Eq Point where
 (Pt x) == (Pt x') = x == x'
instance Ord Point where
 compare (Pt x) (Pt x')
 | x == x' = EQ
 | x < x' = LT
 | otherwise = GT
main = do print $ (Pt 1) == (Pt 2) -- 出力: False
 print $ (Pt 1) >= (Pt 2) -- 出力: False
 print $ (Pt 1) <= (Pt 2) -- 出力: True




6. deriving 宣言

クラスメソッドの実装方法が自明な場合,deriving 宣言を用いると,instance 宣言を省略できます.

data Point = Pt Double Double deriving Eq
main = do print $ (Pt 1 2) == (Pt 1 2) -- 出力: True
 print $ (Pt 1 2) == (Pt 2 3) -- 出力: False


deriving 宣言に複数の型クラスを指定するには,次のように書きます.

data Point = Pt Double Double deriving (Show, Read, Eq)




7. 標準の型クラス

標準で定義されている型クラスには,次のようなものがあります.

  • Eq クラス: 等値性が評価可能な型を表します.

  • Ord クラス: 順序付けの可能な型を表します.

  • Num クラス: 数値として扱われる型を表します.インスタンスには Int, Integer, Float, Double 等があります.

class Num a where
 (+), (*), (-) :: a -> a -> a
 negate, abs, signum :: a -> a
 fromInteger :: Integer -> a


  • Show クラス: 文字列化可能な型を表します.

data Point = Pt Double Double deriving Show
main = do putStrLn $ show (Pt 2 3) -- 出力: Pt 2.0 3.0
 print (Pt 2 3) -- 出力: Pt 2.0 3.0


  • Read クラス: 文字列から変換可能な型を表します.

data Point = Pt Double Double deriving (Read, Show)
main = do print (read "Pt 3 4" :: Point) -- 出力: Pt 3.0 4.0


  • Enum クラス: 列挙型を表します.列挙型を要素とするリストには,数列表記が使えます.

data Day = Sun | Mon | Tue | Wed | Thu | Fri | Sat
 deriving (Enum, Show)
main = print [Mon .. Fri] -- 出力: [Mon, Tue, Wed, Thu, Fri]


  • Bounded クラス: 上限,下限を持つ型を表します.

data Day = Sun | Mon | Tue | Wed | Thu | Fri | Sat
 deriving (Enum, Bounded, Show)
main = do print $ (minBound :: Day) -- 出力: Sun
 print $ (maxBound :: Day) -- 出力: Sat




8. カインド

ここでは VW ザビートル用 スタッドレス ミシュラン エックスアイス3プラス 215/60R16 99H XL ユーロ AFG タイヤホイール4本セット,"型の型" に相当する概念である カインド(kind)を紹介します.

リストや Maybe 型は,ある値を箱の中に入れたような構造を取ります. こうした型を表す型クラス Container を,次のように定義してみます.

class Container c where
 cmap :: (a -> b) -> c a -> c b


関数 cmap は,関数 map の一般化であり,コンテナの中の値を操作します. 次のプログラムは 255/50R19 スタッドレスタイヤ ホイールセット 【送料無料】【2018年製】 STEINER VS5 19x8.0 45 114.3x5 BK/P + NANKANG ESSN-1 255/50R19 107Q XL スタッドレス (255/50/19 255-50-19) 冬タイヤ 19インチ,MaybeContainer クラスのインスタンスとしたものです.

class Container c where
 cmap :: (a -> b) -> c a -> c b
instance Container Maybe where
 -- cmap :: (a -> b) -> Maybe a -> Maybe b
 cmap f Nothing = Nothing
 cmap f (Just x) = Just (f x)
main = do print $ cmap (2*) Nothing -- 出力: Nothing
 print $ cmap (2*) (Just 3) -- 出力: Just 6


関数 cmap の型宣言を吟味すると,Container クラスのインスタンスは Maybe であって,Maybe a ではないことがわかります. Container クラスのインスタンスは,具体型を取り具体型を返す,一種の高階の型であると言えます.

Container クラスのインスタンスのカインドは,* -> * と書かれます. ここで,カインド * は何らかの具体的な型を表します. カインド * -> * は,具体的な型を取り,具体的な型を返す型を表します. Maybe :: * -> * であり,

18インチジュークF15系ENKEI パフォーマンスライン PF07 ダークシルバー 7.5Jx18Bluearth エース AE50 225/45R18激安セール!

Int :: * なので,

18インチジュークF15系ENKEI パフォーマンスライン PF07 ダークシルバー 7.5Jx18Bluearth エース AE50 225/45R18

Maybe Int のカインドは * です.

{yahoojp} {walk.northcol.org}
{yahoojp}jpprem01-zenjp40-wl-zd-64023