newtype と 遅延評価
undefined
という値がある。これは、ぶっ壊れた計算を表す。
この値を評価すると Haskell はすごく怒る。
*Main> undefined *** Exception: Prelude.undefined CallStack (from HasCallStack): error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err undefined, called at <interactive>:14:1 in interactive:Ghci3
すなわち例外を投げる。
しかし、undefined
を含むリストを作っても、undefined
の要素を要求しなければ、
例外発生せずに処理される。
*Main> head [3,4,5,undefined,2,undefined] 3
Haskell は先頭要素以外を評価しないためである。
ここで以下のような型を作る
data CoolBool = CoolBool { getCoolBool :: Bool }
中身の Bool が True か False かどうかによらず、'hello' を返す関数を書く。
helloMe :: CoolBool -> String helloMe (CoolBool _) = "hello"
この関数を、CoolBool 値ではなく undefined
に適用してみる。
*Main> helloMe undefined "*** Exception: Prelude.undefined CallStack (from HasCallStack): error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err undefined, called at <interactive>:21:9 in interactive:Ghci1
data キーワードで定義された方には複数の値コンストラクタがあるかもしれないので、
関数の引数が (CoolBool _)
に合致するかどうかを確認するためには、
どのコンストラクタが使われたのか分かるところまで引数の評価を進める必要がある。
そして、undefined
を評価しようとして例外が発生している。
今度は、CoolBool を newtype で定義する。
newtype CoolBool = CoolBool { getCoolBool :: Bool }
同じように関数を適用してみる
*Main> helloMe undefined "hello"
例外が発生しない。
newtype
キーワードはコンストラクタを1つしか作れないことを Haskell は知っているため、
引数が (CoolBool _)
パターンに合致すると判定できる。
data
はオリジナルな型を無から作り出すものnewtype
は既存の型をもとにはっきり区別される新しい型を作るものdata
に対するパターンマッチは箱から中身を取り出す操作newtype
に対するパターンマッチはある型を別の型に直接変換する操作
type vs. newtype vs. data
type
型シノニムを作るためのもの
type IntList = [Int]
型注釈にどちらの名前を使うかは自由
*Main> ([1,2,3] :: IntList) ++ ([1,2,3] :: [Int]) [1,2,3,1,2,3]
型シノニムは型シグネチャを整理してわかりやすくしたい時に使う。
[(String, String)]
を PhoneBook
という名前で扱えるようにするなど。
newtype
既存の型を包んで新しい型を作るためのもの
newtype CharList = CharList { getCharList :: [Char] }
この場合、CharList
と [Char]
を ++
で連結することはできない。
++
はリスト限定の演算子なので無理。
newtype
宣言でレコード構文を使うと、newtype
の値コンストラクタと、
フィールド内の値を取り出す関数が作られる。
新しい型は、元の型の所属していた型クラスを引き継がないので、deriving
で導出するか、
インスタンス宣言を手書きするか、GeneralizedNewtypeDeriving
を使う必要がある。
data
data
は自作の新しいデータ型を作るためのもの。
3つの使い分け方
- 型宣言を整理したい、型名が体を表すようにしたいだけなら
type
- 既存の型をある型クラスのインスタンスにしたくて、新しい型にくるむなら
newtype
- まったく新しいものを作るなら
data
所感
3つのデータ型宣言の違いがなんとなくわかった。
モノイドはいまだ登場せず。

- 作者: MiranLipovaca
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る