mike-neckのブログ

Java or Groovy or Swift or Golang

『ふつうのHaskell』第九章

単なる読書メモ

代数的データ型

定義の仕方1 - 構造体っぽい

ラベルなしコンストラクター

-- Student型の定義
data Student = Student String String
-- インスタンス化
student = Student "Paul" "Smith"
-- パターンマッチ
printStudent:: Student -> IO()
printStudent (Student fn ln) = print (fn ++ " " ++ ln)

ラベルありコンストラクター

-- Student型の定義
data Student = Student {
    fstName:: String,
    lstName:: String
}
-- インスタンス化
student = Student {fstName = "Paul", lstName = "Smith"}
-- パターンマッチ
printStudent:: Student -> IO()
printStudent Student{fstName = fn, lstName = ln} = putStrLn (fn ++ " " ++ ln)
-- fstNameだけを取り出す関数fstNameが自動で生成される
printFirstName:: Student -> IO()
printFirstName = putStrLn $ fstName
-- 値を更新した新しいStudentオブジェクトの生成
replaceFirstName:: Student -> String -> Student
replaceFirstName student fn = student {fstName = fn}

多層的な型

data Stack = Stack[a]

定義の仕方2 - enum

-- 色型の定義
data Color = Black | White | Green | Red | Blue | Purple | Yellow | Orange | Cyan

定義の仕方 - 共用体っぽい

-- スタックの定義
data Stack a = Empty | Push a (Stack a)
-- スタックに対する操作の定義
(|>) :: a -> Stack a -> Stack a
x |> stk = Push x (stk)
infixr 5 |>
isEmptyStack:: Stack a -> Bool
isEmptyStack Empty = True
isEmptyStack _ = False
popStack:: Stack a -> (a, Stack a)
popStack (Push x stk) = (x, stk)

型の別名

-- StringにFilePathという別名を付与する
type FilePath = String

型クラス

  • 多相型に対して制約を付ける場合に利用する
  • 型ではない
  • 制約したインスタンスに対して適用できる関数をクラスメソッドという

定義の仕方

class Matrix a where
    (***):: a -> a -> Float

クラスの継承

型クラスOrd aは型クラスEq aを継承しているので次のような定義になっている

class (Eq a) => Ord a where
    compare:: a -> a -> Ordering
    (<), (<=), (>), (>=):: a -> a -> Bool
    max, min:: a -> a -> a

インスタンス宣言

型を型クラスのインスタンスであると宣言する方法

-- 型クラスAppendの定義
class (Eq a) => Matrix a where
    (***):: a -> a -> Float
-- スタック型の定義
data Vector = Vec Float Float
-- インスタンス宣言
instance Matrix Vector where
    (Vec x y) *** (Vec a b) = x * a + y * b
instance Eq Vector where
    (Vec x y) == (Vec a b) = (x == a) && (y == b)

HaskellHaskellでこれまでのJava言語圏で生きてきた僕にはなかなかつらいところがあったりする。特にコンパイル時の型推論によるコンパイルエラーなど。まあ、でも意地になってググったりしてやってて、それはそれで楽しい。