fugafuga.write

日々のログ



すごいH本 part8

やっていきの精神

型変数

*Main Lib> :t head
head :: [a] -> a
  • aが型変数
  • aはどんな型もとり得る
  • 型変数を用いた関数は多相的関数と呼ばれる
  • 型変数はa,bなど1文字で表現されることが多い

型クラス

  • 何らかの振る舞いを定義するインターフェース
  • 型は型クラスのインスタンス
  • インスタンスは型クラスの振る舞いを実装する
*Main Lib> :t (==)
(==) :: Eq a => a -> a -> Bool
  • 関数の名前が特殊文字からのみなる場合、デフォルトで中置関数になる
  • 前置関数として使いたい場合は、(==) のように丸括弧をつける
  • =>より前にあるものは型クラス制約と呼ばれる
    • Eq aの部分を指す

ある型の 2 つの値の等値性を比較することに意味があるなら、その型は 型ク ラスのインスタンスにできます。

ここがよくわからん

Eq 型クラス

  • 等値性をテストできる型に使われる
  • インターフェースは ==/=

Ord 型クラス

  • 何らかの順序を付けられる型のためのクラス
  • <,>,<=,>=の関数をサポートする
*Main Lib> :t (>)
(>) :: Ord a => a -> a -> Bool

Show 型クラス

  • Show 型クラスのインスタンスは文字列として表現できる
  • 関数以外の型は Show 型クラスのインスタンス
-- 与えられた値を文字列として表示する
*Main Lib> :t show
show :: Show a => a -> String
*Main Lib> show 3
"3"

Read 型クラス

  • Show と対をなす
  • 全ての型はこの型クラスのインスタンス
-- 与えられた文字列をRead型として返す
*Main Lib> :t read
read :: Read a => String -> a
*Main Lib> read "True" || False
True
*Main Lib> read "3432" + 3
3435
  • 入力が"3"だけなどの場合、エラーとなる
  • Read型が返るが、返された値を使わない場合型推論できなくなる
*Main Lib> read "3"
*** Exception: Prelude.read: no parse

この問題を解決するために 型注釈 を使う

式の後ろに:: {型} を書く

 *Main Lib> read "3" :: Int
3

Enum 型クラス

  • 要素の値を列挙できる型
  • 値をレンジで使うことができる

Bounded 型クラス

  • 上限と下限を持つ
  • 多相定数といえる
*Main Lib> :t minBound
minBound :: Bounded a => a
*Main Lib> :t maxBound
maxBound :: Bounded a => a
*Main Lib> minBound :: Int
-9223372036854775808
*Main Lib> maxBound :: Int
9223372036854775807
*Main Lib> minBound :: Char
'\NUL'
*Main Lib> maxBound :: Char
'\1114111'

タプルの全ての要素がBounded型の場合、そのタプル自身がBounded型になる

*Main Lib> maxBound :: (Bool, Int, Char)
(True,9223372036854775807,'\1114111')

Num 型クラス

  • 数の型クラス
*Main Lib> :t 20
20 :: Num t => t
  • 多相定数として表現される
*Main Lib> 20 :: Int
20
*Main Lib> 20 :: Float
20.0
*Main Lib> 20 :: Double
20.0

Floating 型クラス

  • Float と Double の型が含まれる
*Main Lib> :t sin
sin :: Floating a => a -> a
*Main Lib> sin 3
0.1411200080598672

Integral 型クラス

  • Num と同じく数を表現する
  • Num は 実数を含む全ての数を表現する
  • Integral は整数のみ
*Main Lib> :t fromIntegral
fromIntegral :: (Num b, Integral a) => a -> b
  • 整数をとり、何らかの数を返す
  • fromIntegralは整数と小数を同時に扱いたい場合に使うとよい
*Main Lib> fromIntegral (length [1,2,3]) + 2.5
5.5

型クラスと型の関係

  • 型クラスは型を複数持てる
  • 型をある型クラスのインスタンスにするために、別のインスタンスにする必要がある場合がある
    • Eq クラスのインスタンスであることは、Ord クラスのインスタンスになることの必要条件である

まとめ

  • 型変数とはどんな型でも取り得るもの
  • 型クラスとは型のインターフェース
  • 型は複数の型クラスを実装することができる

今日はここまで。

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

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