🗂

代表的な型クラス一覧(Haskell)

2022/04/29に公開

この記事では、代表的な型クラスをご紹介します。

型クラスとはデータ型をグループ化し、関数を実装させるための仕組みです。 その中から代表的な型クラスをご紹介します。(そもそも型クラスとは何か?についてはこちらの記事から

Num型クラス

数値として計算させるための型クラスです。:iコマンドで情報を調べてみます。

Prelude> :i Num
type Num :: * -> Constraint
class Num a where
  (+) :: a -> a -> a
  (-) :: a -> a -> a
  (*) :: a -> a -> a
  negate :: a -> a
  abs :: a -> a
  signum :: a -> a
  fromInteger :: Integer -> a
  {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}
        -- Defined in ‘GHC.Num’
instance Num Word -- Defined in ‘GHC.Num’
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Int -- Defined in ‘GHC.Num’
instance Num Float -- Defined in ‘GHC.Float’
instance Num Double -- Defined in ‘GHC.Float’
:

まずは下の部分から見ていきます。instance Num Word、instance Num Integerなどがありますが、こちらがNum型クラスに所属するデータ型です。インスタンスとは型クラスに所属するデータ型のことです。(オブジェクト指向のインスタンスとごっちゃにならないよう気をつけて下さい。)計算をするNum型クラスには、Word、Integer、Int、Float、Doubleの合計5つのデータ型が属しています。

次に上の部分です、+、-、*、negate、absなどの演算子があります。演算子は関数として提供されていることを思い出して下さい。ここではNum型クラスに所属するデータ型に対して、実装させる関数を決めています。つまりIntやDoubelなどのデータ型は、+や-などで計算できる..ということを表しています。

Ord型クラス

比較をするための関数を提供し、それができるデータ型を集めた型クラスです。

Prelude> :i Ord
type Ord :: * -> Constraint
class Eq a => Ord a where
  compare :: a -> a -> Ordering
  (<) :: a -> a -> Bool
  (<=) :: a -> a -> Bool
  (>) :: a -> a -> Bool
  (>=) :: a -> a -> Bool
  max :: a -> a -> a
  min :: a -> a -> a
  {-# MINIMAL compare | (<=) #-}
  	-- Defined in ‘GHC.Classes’
instance Ord a => Ord [a] -- Defined in ‘GHC.Classes’
instance Ord Word -- Defined in ‘GHC.Classes’
instance Ord Ordering -- Defined in ‘GHC.Classes’
instance Ord Int -- Defined in ‘GHC.Classes’
instance Ord Float -- Defined in ‘GHC.Classes’
instance Ord Double -- Defined in ‘GHC.Classes’
instance Ord Char -- Defined in ‘GHC.Classes’
instance Ord Bool -- Defined in ‘GHC.Classes’
:

実装させる関数としては、<、>、>=、<=などの機能を提供しています。Ord型クラスに所属するデータ型としては、Int、Float、Charなども不等号で比較ができます。(Stringは不等号で比較できないのでOrd型クラスには含まれません。)

Orderingというのが初めて出てきました。こちらはcompare関数が提供する機能の1つです。

Prelude> :t compare
compare :: Ord a => a -> a -> Ordering
Prelude> :i Ordering
type Ordering :: *
data Ordering = LT | EQ | GT
  	-- Defined in ‘GHC.Types’
:

compare関数は引数を2つ受け取り、Orderingを返却します。OrderingはGT、LT、EQのどれかの値を取ります。つまり より大きい、より小さい、等しい..を判定します。

Eq型クラス

値が同じかどうかを判定するための型クラスです。

Prelude> :i Eq
type Eq :: * -> Constraint
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  {-# MINIMAL (==) | (/=) #-}
  	-- Defined in ‘GHC.Classes’
instance Eq a => Eq [a] -- Defined in ‘GHC.Classes’
instance Eq Word -- Defined in ‘GHC.Classes’
instance Eq Ordering -- Defined in ‘GHC.Classes’
instance Eq Int -- Defined in ‘GHC.Classes’
instance Eq Float -- Defined in ‘GHC.Classes’
instance Eq Double -- Defined in ‘GHC.Classes’
instance Eq Char -- Defined in ‘GHC.Classes’
instance Eq Bool -- Defined in ‘GHC.Classes’
:

==、/=の関数を提供しています。

Show型クラス

文字列へ変換するための型クラスです。

Prelude> :i Show
type Show :: * -> Constraint
class Show a where
  showsPrec :: Int -> a -> ShowS
  show :: a -> String
  showList :: [a] -> ShowS
  {-# MINIMAL showsPrec | show #-}
  	-- Defined in ‘GHC.Show’
instance Show a => Show [a] -- Defined in ‘GHC.Show’
instance Show Word -- Defined in ‘GHC.Show’
instance Show GHC.Types.RuntimeRep -- Defined in ‘GHC.Show’
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show Int -- Defined in ‘GHC.Show’
instance Show Char -- Defined in ‘GHC.Show’
instance Show Bool -- Defined in ‘GHC.Show’
:

Show型クラスが使われる代表がprint関数です。

Prelude> :t (print)
(print) :: Show a => a -> IO ()

Show型クラスに所属するデータ型の値を受け取り、それにShowを提供して文字列化してから、画面に出力する..といった処理を内部で行います。

Read型クラス

文字列をRead型クラスに所属するデータ型の値に変換して、出力するための仕組みです。(Show型クラスとは逆の性質を持ちます。)

Prelude> :i Read
type Read :: * -> Constraint
class Read a where
  readsPrec :: Int -> ReadS a
  readList :: ReadS [a]
  GHC.Read.readPrec :: Text.ParserCombinators.ReadPrec.ReadPrec a
  GHC.Read.readListPrec :: Text.ParserCombinators.ReadPrec.ReadPrec
                             [a]
  {-# MINIMAL readsPrec | readPrec #-}
  	-- Defined in ‘GHC.Read’
instance Read a => Read [a] -- Defined in ‘GHC.Read’
instance Read Word -- Defined in ‘GHC.Read’
instance Read Ordering -- Defined in ‘GHC.Read’
instance Read a => Read (Maybe a) -- Defined in ‘GHC.Read’
instance Read Integer -- Defined in ‘GHC.Read’
instance Read Int -- Defined in ‘GHC.Read’
instance Read Float -- Defined in ‘GHC.Read’
instance Read Double -- Defined in ‘GHC.Read’
instance Read Char -- Defined in ‘GHC.Read’
instance Read Bool -- Defined in ‘GHC.Read’

Read型クラスに所属するデータ型の内、任意のモノとなる点に注意が必要です。read関数を使ってその仕組みを確認します。read関数とは文字列を受け取り、Readに属するデータ型の値を返却します。

Prelude> read "10" + 20
30

こちらは+ 20とあるので、データ型を推測できます。しかし以下の場合だと、Read型クラスにあるデータ型の中でどれを返せば良いのかわかりません。

Prelude> read "10"

なので返却すべきデータ型を指定するようにします。

Prelude> read "10" ::Int
10

例えばこちらのプログラムは手がかりがあるので、文字列→任意のデータ型に変換できます。

Enum型クラス

そのデータ型が持つ値を列挙できるか?を扱う型クラスです。

Prelude> :i Enum
type Enum :: * -> Constraint
class Enum a where
  succ :: a -> a
  pred :: a -> a
  toEnum :: Int -> a
  fromEnum :: a -> Int
  enumFrom :: a -> [a]
  enumFromThen :: a -> a -> [a]
  enumFromTo :: a -> a -> [a]
  enumFromThenTo :: a -> a -> a -> [a]
  {-# MINIMAL toEnum, fromEnum #-}
  	-- Defined in ‘GHC.Enum’
instance Enum Word -- Defined in ‘GHC.Enum’
instance Enum Ordering -- Defined in ‘GHC.Enum’
instance Enum Integer -- Defined in ‘GHC.Enum’
instance Enum Int -- Defined in ‘GHC.Enum’
instance Enum Char -- Defined in ‘GHC.Enum’
instance Enum Bool -- Defined in ‘GHC.Enum’
instance Enum () -- Defined in ‘GHC.Enum’
instance Enum Float -- Defined in ‘GHC.Float’
instance Enum Double -- Defined in ‘GHC.Float’

succ関数やpred関数は、その1コ後、1コ前の値を出力する機能を持っていました。

Prelude> succ 10
11
Prelude> pred 10
9

Bounded型クラス

上限と下限を持つデータ型をまとめた型クラスです。

Prelude> :i Bounded
type Bounded :: * -> Constraint
class Bounded a where
  minBound :: a
  maxBound :: a
  {-# MINIMAL minBound, maxBound #-}
  	-- Defined in ‘GHC.Enum’
instance Bounded Word -- Defined in ‘GHC.Enum’
instance Bounded Ordering -- Defined in ‘GHC.Enum’
instance Bounded Int -- Defined in ‘GHC.Enum’
instance Bounded Char -- Defined in ‘GHC.Enum’
instance Bounded Bool -- Defined in ‘GHC.Enum’

注目して頂きたいのがminBoundとmaxBoundが関数ではなく、値である点です。これらの値に対してデータ型を指定するとどうなるでしょうか。

Prelude> minBound :: Int
-9223372036854775808
Prelude> maxBound :: Int
9223372036854775807
Prelude> minBound :: Char
'\NUL'
Prelude> maxBound :: Char
'\1114111'

それぞれの最大値と最小値を求めることができました。Intは上限と下限を持ちますが、Integralはそれがないので気を付けて下さい。

Floating型クラス

浮動小数点を扱うための型クラスです。

Prelude> :i Floating
type Floating :: * -> Constraint
class Fractional a => Floating a where
  pi :: a
  exp :: a -> a
  log :: a -> a
  sqrt :: a -> a
  (**) :: a -> a -> a
  logBase :: a -> a -> a
  sin :: a -> a
  cos :: a -> a
  tan :: a -> a
  asin :: a -> a
  acos :: a -> a
  atan :: a -> a
  sinh :: a -> a
  cosh :: a -> a
  tanh :: a -> a
  asinh :: a -> a
  acosh :: a -> a
  atanh :: a -> a
:

sin、cos、tanなどの関数を提供しているのがわかります。

Discussion