Haskell備忘録

型システム

  • data型 data
  • 型シノニム type
  • 型クラス class

data型を使って型を定義する。
data型は継承できないため、型クラスを使って共通化を行う。
型クラスを実装したdata型はその型クラスのインスタンスと呼ぶ。

data型

Haskelの型。代数的データ型。

data 型名 = 値コンストラクタ1 | 値コンストラクタ2 引数1 引数2 

1つ以上の値コンストラクタを持ち、値コンストラクタは0個以上の引数を持つ。 値コンストラクタが1つのときは、型名と同名にするのが慣例。

例: 信号機

data TrafficLight = Red | Yellow | Green

例: 引数を持つ場合

data Shape = Rectangle Int Int Int Int | 
             Circle Int Int Int

多層型 (型コンストラクタ)

ジェネリックス型。

data Vector a = Vector a a a
項目
a 型引数 (type paramter)

型クラス制約は関数もしくはインスタンス実装時に定義する。

vplus:: (Num t) => Vector t -> Vector t -> Vector t
(Vector i j k) `vplus` (Vector l m n) = Vector (i+l) (j+m) (k+n)

型クラス

class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool
    x == y = not (x /= y)
    x /= y = not (x == y)
項目
Eq 型クラス名
a 型変数 (type variable) 具体型である必要がある。将来のインスタンス
(==) :: a -> a -> Bool 関数の定義 型クラスのインスタンス化時に実装する必要がある
x == y = not (x /= y) 関数のデフォルト実装 型クラス側で関数を実装することが可能。インスタンス化された型から呼び出すことが出来る。

備考

Eq型クラスのインスタンスにする場合は、(==) もしくは (/=) 関数のどちらかを実装するだけでよい。

サブクラス化

型変数に対して型クラス制約することでその型クラスのサブクラスとなる。 Num型クラスは Eqのサブクラス

class (Eq a) => Num a where

型クラスのインスタンスにする

instance Show TrafficLight where 
    show Red = "Red light"
    show Yellow = "Yellow light"
    show Green = "Green lignt"
  • Show 型クラス

多層型を型クラスのインスタンスにする

多層型の場合、型引数を伴って具体型となる。

instance Eq a => Eq Vector a where
    (Vector x1 y1 z1) == (Vector x2 y2 z2) = (x1 == x2) && (y1 == y2) && (z1 == z2)
  • Eq a => 型クラス制約
  • Vector 型コンストラク
  • Vector a 具体型

型クラスの自動導出 deriving

derivingキーワードを使うことで、特定の型クラスのインスタンスに自動導出される。

data Point = Point Int Int deriving Show

型クラス 初級

Eq 型クラス

等値性をテストできる型のための型クラス。

Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Prelude> :t (/=)
(/=) :: Eq a => a -> a -> Bool

Ord 型クラス

順序付けられる型のための型クラス。

Prelude> :t (>)
(>) :: Ord a => a -> a -> Bool

Show 型クラス

文字列として表現できる型のための型クラス

Prelude> show 5
"5"

Read 型クラス

Showとは反対に、文字列から型に変換することが出来るための型クラス

Prelude> read "5" :: Int
5
Prelude> read "5" :: Float
5.0
Prelude> read "5" - 2
3
Prelude> read "True" || False
True

Enum 型クラス

列挙できる型のための型クラス

Prelude> [3 .. 5]
[3,4,5]
Prelude> ['a' .. 'e']
"abcde"
Prelude> [LT .. GT]
[LT,EQ,GT]
Prelude> succ 'B'
'C'

その他

型クラス 説明
Bounded 上限、下限を持つ
Num Int, Integer, Float, Doubleなどがインスタンス
Floating Float, Double がインスタンス
Integral Numが実数を含む全ての数を表すのに対して、整数のみが含まれる

型シノニム

[Char]String は同地で交換可能。これは 型シノニム を使って実装されている。

type String = [Char]

型シノニムの多層化

type IntMap = Map Int
  • Map 型コンストラクタ - 型引数をともなって初めて具体型となる

YesNo型クラス

class YesNo a where
    yesno :: a -> Bool
instance YesNo Int where
    yesno 0 = False
    yesno _ = Yes
instance Integral a => YesNo (Maybe a) where
    yesno (Just x) = x `mod` 2 == 0
    yesno Nothing = False

Rustとの関係

Rustのstructも data型と同じように継承ができない。 またトレイトと型クラスが対応していると考えられる。

参照

すごいHaskellたのしく学ぼう! | Miran Lipovača, 田中 英行, 村主 崇行 |本 | 通販 | Amazon