10.1 typeによる型宣言
type
キーワードは型のエイリアスに名前をつける方法。再帰定義はできない。
type Assoc k v = [(k,v)] find :: Eq k => k -> Assoc k v -> v find k t = head [v | (k',v) <- t, k == k']
newtype
キーワードは教科書に出て来てないなあ。
10.2 dataによる型宣言
data
はデータコンストラクタ(構築子)を並べる型宣言。
下の例だと、Left
、Right
、Up
、Down
が引数なしのデータコンストラクタ。
要するに、型Move
は列挙型ということ。
-- nullary data constructor type Pos = (Int,Int) data Move = Left_ | Right_ | Up_ | Down_ move :: Move -> Pos -> Pos move Left_ (x,y) = (x-1, y) move Right_ (x,y) = (x+1, y) move Up_ (x,y) = ( x,y-1) move Down_ (x,y) = ( x,y+1) moves :: [Move] -> Pos -> Pos moves [] p = p moves (m:ms) p = moves ms (move m p) flip :: Move -> Move flip Left_ = Right_ flip Right_ = Left_ flip Up_ = Down_ flip Down_ = Up_
下の例は、Circle
が1引数のデータコンストラクタ、Rect
が2引数のデータコンストラクタ。
-- unary/binary data constructor data Shape = Circle Float | Rect Float Float square :: Float -> Shape square n = Rect n n area :: Shape -> Float area (Circle r) = pi * r ^ 2 area (Rect x y) = x * y
多相型(型引数付き)も定義可能。ここでMaybe a
が例に登場。
-- polymorphic data constructor with a type parameter -- (data Maybe a = Nothing | Just a) safediv :: Int -> Int -> Maybe Int safediv _ 0 = Nothing safediv m n = Just (m `div` n) safehead :: [a] -> Maybe a safehead [] = Nothing safehead xs = Just (head xs)