SlideShare a Scribd company logo
すごいHaskell本
              2章: 型を信じろ!
                 小嶋智 @skoji




12年6月23日土曜日
• Haskell学びはじめて1ヶ月なので
              • 間違いあったら遠慮無く突っ込んでく
               ださい




12年6月23日土曜日
強力な型システム
              • 型に関するエラーはコンパイル時に検
               知できる

              • (型の自動変換はない)
              • 型推論がある
              • 型システムをしっかり理解しよう

12年6月23日土曜日
GHCiで型を調べる
              Prelude> :t 'a'
              'a' :: Char
              Prelude> :t True
              True :: Bool
              Prelude> :t "HELLO"
              "HELLO" :: [Char]
              Prelude> :t 4 == 5
              4 == 5 :: Bool
              Prelude> let removeNonUppercase st = [ c | c <- st, c
              `elem` ['A'..'Z']]
              Prelude> :t removeNonUppercase
              removeNonUppercase :: [Char] -> [Char]
              Prelude>




12年6月23日土曜日
GHCiで型を調べる(2)

         Prelude> let removeNonUppercase st = [ c | c <- st, c
         `elem` ['A'..'Z']]
         Prelude> :t removeNonUppercase
         removeNonUppercase :: [Char] -> [Char]
         Prelude>




12年6月23日土曜日
型宣言は良い習慣


              removeNonUppercase :: [Char] -> [Char]

              removeNonUppercase st = [ c | c <- st, c `elem`
              ['A'..'Z']]




12年6月23日土曜日
GHCiの中で型宣言

              Prelude>   let { addThree :: Int -> Int -> Int -> Int;
              addThree   x y z = x + y + z }
              Prelude>   :t addThree
              addThree   :: Int -> Int -> Int -> Int
              Prelude>




12年6月23日土曜日
引数と返り値の区切
                                                       詳しくは5章で


         Prelude>   let { addThree :: Int -> Int -> Int -> Int;
         addThree   x y z = x + y + z }
         Prelude>   :t addThree
         addThree   :: Int -> Int -> Int -> Int
         Prelude>




12年6月23日土曜日
一般的なHaskellの型(1)


              • Int : 整数・有界
              • Integer : 整数・有界じゃない
              • Float : 単精度浮動小数点数
              • Double : 倍精度浮動小数点数

12年6月23日土曜日
一般的なHaskellの型(2)


              • Bool :真理値型 (True, False)
              • Char : ユニコード文字。Charのリスト
               は文字列

              • タプル: 要素数と要素の型で型が決まる

12年6月23日土曜日
型変数

              Prelude> :t head
              head :: [a] -> a    型変数

         ちょっとGenericsぽいけどもっと強力。


                こういうのを「多相的関数」という




12年6月23日土曜日
型変数(2)

              Prelude> :t fst
              fst :: (a, b) -> a

         タプルの1要素目と戻り値の型が同じ。2要素目は
         違う型でもよいし、同じでもよい。




12年6月23日土曜日
型クラス初級講座


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




12年6月23日土曜日
Eq a => ?


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




12年6月23日土曜日
型クラス制約
         Prelude> :t (==)
         (==) :: Eq a => a -> a -> Bool

         型aはEq型クラスのインスタンスでなくてはなら
         ない。
              型クラスはオブジェクト指向のクラスとは
                    違うので注意!



12年6月23日土曜日
型クラス制約
         Prelude> :t (==)
         (==) :: Eq a => a -> a -> Bool

         型aはEq型クラスのインスタンスでなくてはなら
         ない。
              型クラスはオブジェクト指向のクラスとは
                    違うので注意!
                                  詳しくはもっと先
                                  で分かる、はず


12年6月23日土曜日
Eq型
              Eqのインスタンスが実装すべき関数:

                         ==と/=

         Prelude> 5 == 5
         True
         Prelude> 5 /= 5
         False
         Prelude> "foo" == "bar"
         False


12年6月23日土曜日
型制約の意味

              • 関数の型変数にEqクラスの制約がつい
               ている

              • ならば、関数の定義のなかで、==か/=
               が使われている




12年6月23日土曜日
いろんな型クラス


              • Ord, Show, Read, Enum, Bounded,
               Num, Floating, Integral




12年6月23日土曜日
Ord

         • 順序づけのある型のための型クラス
         Prelude> :t (>)
         (>) :: Ord a => a -> a -> Bool

         •> < >= <=   をサポート



12年6月23日土曜日
compare関数
         Prelude>   "Abc" >= "Zed"
         False
         Prelude>   "Abc" `compare` "Zed"
         LT
         Prelude>   5 >= 2
         True
         Prelude>   5 `compare` 2
         GT




12年6月23日土曜日
Show型クラス
         • Show型クラスのインスタンスが型であ
              る値は、文字列として表現可能

         Prelude> show 3
         "3"
         Prelude> show 5.334
         "5.334"
         Prelude> show True
         "True"

12年6月23日土曜日
Read型クラス

         • Showと対をなす。read関数は文字列を
              受け取って、Readのインスタンスの型
              の値を返す。

         Prelude> :t read
         read :: Read a => String -> a



12年6月23日土曜日
readの例
         Prelude> read   "True" || False
         True
         Prelude> read   "8.2" + 3.8
         12.0
         Prelude> read   "5" - 2
         3
         Prelude> read   "[1,2,3,4]" ++ [3]
         [1,2,3,4,3]


12年6月23日土曜日
readできない!

              Prelude> read "4"

         <interactive>:1:1:
             Ambiguous type variable `a0' in the constraint:
               (Read a0) arising from a use of `read'
             Probable fix: add a type signature that fixes these
         type variable(s)
             In the expression: read "4"
             In an equation for `it': it = read "4"




12年6月23日土曜日
型注釈
         Prelude> read "4" :: Int
         4
         Prelude> read "4" :: Float
         4.0
         Prelude> (read "4" :: Float) * 5
         20.0
         Prelude> read "[1,2,3,4]" :: [Int]
         [1,2,3,4]
         Prelude> read "(3, 'a')" :: (Int, Char)
         (3,'a')




12年6月23日土曜日
型注釈不要な場合

         Prelude> [read "True" :: Bool , False]
         [True,False]

         Prelude> [read "True", False, True, False]
         [True,False,True,False]




12年6月23日土曜日
Enum型クラス
              • 「順番に並んだ型」
              • 要素の値を列挙できる
              • レンジの中で使える
              • 有界じゃないIntegerもEnum型
              • C言語的なEnumとは違いますね!
12年6月23日土曜日
Enumの例
           Prelude> ['a'..'e']
         "abcde"
         Prelude> [LT .. GT]
         [LT,EQ,GT]
         Prelude> [3 .. 5]
         [3,4,5]
         Prelude> succ 4
         5
         Prelude> pred 'Z'
         'Y'


12年6月23日土曜日
Bounded型クラス
         • 上限と下限をもつ
         • minBound, maxBound関数
         Prelude> minBound :: Int
         -9223372036854775808
         Prelude> maxBound :: Char
         '1114111'
         Prelude> maxBound :: Bool
         True


12年6月23日土曜日
多相定数


         Prelude> :t minBound
         minBound :: Bounded a => a




12年6月23日土曜日
Num型クラス

         • 数のように振る舞う。
         • 数の型を調べると:
         Prelude> :t 20
         20 :: Num a => a



12年6月23日土曜日
数は多相定数
         Prelude>   20 :: Int
         20
         Prelude>   20 :: Integer
         20
         Prelude>   20 :: Float
         20.0
         Prelude>   20 :: Double
         20.0


12年6月23日土曜日
Numを使う演算子
          Prelude> :t (*)
         (*) :: Num a => a -> a -> a

         •aの型はNum型クラスのインスタンス
         •ふたつの引数は同じ型
         •Int * IntはOKだが、Int * Integer
         は型エラー


12年6月23日土曜日
Floating型クラス
         • FloatとDoubleが含まれる
         • 結果を小数点で表現できないと意味のあ
              る計算ができない関数で使う: sin,
              cos ,sqrt など。

         Prelude> :t sin
         sin :: Floating a => a -> a


12年6月23日土曜日
Integral型クラス

              • Numは実数を含むが、Integralは整数
               全体のみが含まれる。

              • IntとIntegerを含む


12年6月23日土曜日
fromIntegral

         Prelude> :t fromIntegral
         fromIntegral :: (Num b, Integral a) => a -> b
         Prelude> :t length
         length :: [a] -> Int
         Prelude> fromIntegral (length [1,2]) + 3.2
         5.2


         •整数と浮動小数点数を一緒に扱う時便利


12年6月23日土曜日
いくつかの注意(1)
              • ある型は、複数の型クラスのインスタ
               ンスになれる

              • 型クラスは複数の型をインスタンスに
               もてる

              • 例: CharはEqとOrdとその他いろいろ
               のインスタンス


12年6月23日土曜日
いくつかの注意(2)
              • あるクラスのインスタンスになるには、他の
               クラスのインスタンスになる必要がある事が
               ある。

              • 例: Ordのインスタンスになるには、さきにEq
               のインスタンスになる必要がある

              • 「順序づけられるなら(Ord)、比べることもで
               きるはず(Eq)」


12年6月23日土曜日
ありがとうございました




12年6月23日土曜日

More Related Content

スタートHaskell2 型を信じろ

  • 1. すごいHaskell本 2章: 型を信じろ! 小嶋智 @skoji 12年6月23日土曜日
  • 2. • Haskell学びはじめて1ヶ月なので • 間違いあったら遠慮無く突っ込んでく ださい 12年6月23日土曜日
  • 3. 強力な型システム • 型に関するエラーはコンパイル時に検 知できる • (型の自動変換はない) • 型推論がある • 型システムをしっかり理解しよう 12年6月23日土曜日
  • 4. GHCiで型を調べる Prelude> :t 'a' 'a' :: Char Prelude> :t True True :: Bool Prelude> :t "HELLO" "HELLO" :: [Char] Prelude> :t 4 == 5 4 == 5 :: Bool Prelude> let removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']] Prelude> :t removeNonUppercase removeNonUppercase :: [Char] -> [Char] Prelude> 12年6月23日土曜日
  • 5. GHCiで型を調べる(2) Prelude> let removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']] Prelude> :t removeNonUppercase removeNonUppercase :: [Char] -> [Char] Prelude> 12年6月23日土曜日
  • 6. 型宣言は良い習慣 removeNonUppercase :: [Char] -> [Char] removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']] 12年6月23日土曜日
  • 7. GHCiの中で型宣言 Prelude> let { addThree :: Int -> Int -> Int -> Int; addThree x y z = x + y + z } Prelude> :t addThree addThree :: Int -> Int -> Int -> Int Prelude> 12年6月23日土曜日
  • 8. 引数と返り値の区切 詳しくは5章で Prelude> let { addThree :: Int -> Int -> Int -> Int; addThree x y z = x + y + z } Prelude> :t addThree addThree :: Int -> Int -> Int -> Int Prelude> 12年6月23日土曜日
  • 9. 一般的なHaskellの型(1) • Int : 整数・有界 • Integer : 整数・有界じゃない • Float : 単精度浮動小数点数 • Double : 倍精度浮動小数点数 12年6月23日土曜日
  • 10. 一般的なHaskellの型(2) • Bool :真理値型 (True, False) • Char : ユニコード文字。Charのリスト は文字列 • タプル: 要素数と要素の型で型が決まる 12年6月23日土曜日
  • 11. 型変数 Prelude> :t head head :: [a] -> a 型変数 ちょっとGenericsぽいけどもっと強力。 こういうのを「多相的関数」という 12年6月23日土曜日
  • 12. 型変数(2) Prelude> :t fst fst :: (a, b) -> a タプルの1要素目と戻り値の型が同じ。2要素目は 違う型でもよいし、同じでもよい。 12年6月23日土曜日
  • 13. 型クラス初級講座 Prelude> :t (==) (==) :: Eq a => a -> a -> Bool 12年6月23日土曜日
  • 14. Eq a => ? Prelude> :t (==) (==) :: Eq a => a -> a -> Bool 12年6月23日土曜日
  • 15. 型クラス制約 Prelude> :t (==) (==) :: Eq a => a -> a -> Bool 型aはEq型クラスのインスタンスでなくてはなら ない。 型クラスはオブジェクト指向のクラスとは 違うので注意! 12年6月23日土曜日
  • 16. 型クラス制約 Prelude> :t (==) (==) :: Eq a => a -> a -> Bool 型aはEq型クラスのインスタンスでなくてはなら ない。 型クラスはオブジェクト指向のクラスとは 違うので注意! 詳しくはもっと先 で分かる、はず 12年6月23日土曜日
  • 17. Eq型 Eqのインスタンスが実装すべき関数: ==と/= Prelude> 5 == 5 True Prelude> 5 /= 5 False Prelude> "foo" == "bar" False 12年6月23日土曜日
  • 18. 型制約の意味 • 関数の型変数にEqクラスの制約がつい ている • ならば、関数の定義のなかで、==か/= が使われている 12年6月23日土曜日
  • 19. いろんな型クラス • Ord, Show, Read, Enum, Bounded, Num, Floating, Integral 12年6月23日土曜日
  • 20. Ord • 順序づけのある型のための型クラス Prelude> :t (>) (>) :: Ord a => a -> a -> Bool •> < >= <= をサポート 12年6月23日土曜日
  • 21. compare関数 Prelude> "Abc" >= "Zed" False Prelude> "Abc" `compare` "Zed" LT Prelude> 5 >= 2 True Prelude> 5 `compare` 2 GT 12年6月23日土曜日
  • 22. Show型クラス • Show型クラスのインスタンスが型であ る値は、文字列として表現可能 Prelude> show 3 "3" Prelude> show 5.334 "5.334" Prelude> show True "True" 12年6月23日土曜日
  • 23. Read型クラス • Showと対をなす。read関数は文字列を 受け取って、Readのインスタンスの型 の値を返す。 Prelude> :t read read :: Read a => String -> a 12年6月23日土曜日
  • 24. readの例 Prelude> read "True" || False True Prelude> read "8.2" + 3.8 12.0 Prelude> read "5" - 2 3 Prelude> read "[1,2,3,4]" ++ [3] [1,2,3,4,3] 12年6月23日土曜日
  • 25. readできない! Prelude> read "4" <interactive>:1:1: Ambiguous type variable `a0' in the constraint: (Read a0) arising from a use of `read' Probable fix: add a type signature that fixes these type variable(s) In the expression: read "4" In an equation for `it': it = read "4" 12年6月23日土曜日
  • 26. 型注釈 Prelude> read "4" :: Int 4 Prelude> read "4" :: Float 4.0 Prelude> (read "4" :: Float) * 5 20.0 Prelude> read "[1,2,3,4]" :: [Int] [1,2,3,4] Prelude> read "(3, 'a')" :: (Int, Char) (3,'a') 12年6月23日土曜日
  • 27. 型注釈不要な場合 Prelude> [read "True" :: Bool , False] [True,False] Prelude> [read "True", False, True, False] [True,False,True,False] 12年6月23日土曜日
  • 28. Enum型クラス • 「順番に並んだ型」 • 要素の値を列挙できる • レンジの中で使える • 有界じゃないIntegerもEnum型 • C言語的なEnumとは違いますね! 12年6月23日土曜日
  • 29. Enumの例 Prelude> ['a'..'e'] "abcde" Prelude> [LT .. GT] [LT,EQ,GT] Prelude> [3 .. 5] [3,4,5] Prelude> succ 4 5 Prelude> pred 'Z' 'Y' 12年6月23日土曜日
  • 30. Bounded型クラス • 上限と下限をもつ • minBound, maxBound関数 Prelude> minBound :: Int -9223372036854775808 Prelude> maxBound :: Char '1114111' Prelude> maxBound :: Bool True 12年6月23日土曜日
  • 31. 多相定数 Prelude> :t minBound minBound :: Bounded a => a 12年6月23日土曜日
  • 32. Num型クラス • 数のように振る舞う。 • 数の型を調べると: Prelude> :t 20 20 :: Num a => a 12年6月23日土曜日
  • 33. 数は多相定数 Prelude> 20 :: Int 20 Prelude> 20 :: Integer 20 Prelude> 20 :: Float 20.0 Prelude> 20 :: Double 20.0 12年6月23日土曜日
  • 34. Numを使う演算子 Prelude> :t (*) (*) :: Num a => a -> a -> a •aの型はNum型クラスのインスタンス •ふたつの引数は同じ型 •Int * IntはOKだが、Int * Integer は型エラー 12年6月23日土曜日
  • 35. Floating型クラス • FloatとDoubleが含まれる • 結果を小数点で表現できないと意味のあ る計算ができない関数で使う: sin, cos ,sqrt など。 Prelude> :t sin sin :: Floating a => a -> a 12年6月23日土曜日
  • 36. Integral型クラス • Numは実数を含むが、Integralは整数 全体のみが含まれる。 • IntとIntegerを含む 12年6月23日土曜日
  • 37. fromIntegral Prelude> :t fromIntegral fromIntegral :: (Num b, Integral a) => a -> b Prelude> :t length length :: [a] -> Int Prelude> fromIntegral (length [1,2]) + 3.2 5.2 •整数と浮動小数点数を一緒に扱う時便利 12年6月23日土曜日
  • 38. いくつかの注意(1) • ある型は、複数の型クラスのインスタ ンスになれる • 型クラスは複数の型をインスタンスに もてる • 例: CharはEqとOrdとその他いろいろ のインスタンス 12年6月23日土曜日
  • 39. いくつかの注意(2) • あるクラスのインスタンスになるには、他の クラスのインスタンスになる必要がある事が ある。 • 例: Ordのインスタンスになるには、さきにEq のインスタンスになる必要がある • 「順序づけられるなら(Ord)、比べることもで きるはず(Eq)」 12年6月23日土曜日