スタートhaskell2 型を信じろ

40
すごいHaskell本 2章: を信じろ! 小嶋智 @skoji 12623日土曜日

Upload: satoshi-kojima

Post on 01-Jul-2015

1.454 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: スタートHaskell2 型を信じろ

すごいHaskell本2章: 型を信じろ!

小嶋智 @skoji

12年6月23日土曜日

Page 2: スタートHaskell2 型を信じろ

• Haskell学びはじめて1ヶ月なので

•間違いあったら遠慮無く突っ込んでください

12年6月23日土曜日

Page 3: スタートHaskell2 型を信じろ

強力な型システム•型に関するエラーはコンパイル時に検知できる

• (型の自動変換はない)

•型推論がある

•型システムをしっかり理解しよう

12年6月23日土曜日

Page 4: スタートHaskell2 型を信じろ

GHCiで型を調べるPrelude> :t 'a''a' :: CharPrelude> :t TrueTrue :: BoolPrelude> :t "HELLO""HELLO" :: [Char]Prelude> :t 4 == 54 == 5 :: BoolPrelude> let removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]Prelude> :t removeNonUppercaseremoveNonUppercase :: [Char] -> [Char]Prelude>

12年6月23日土曜日

Page 5: スタートHaskell2 型を信じろ

GHCiで型を調べる(2)

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

12年6月23日土曜日

Page 6: スタートHaskell2 型を信じろ

型宣言は良い習慣

removeNonUppercase :: [Char] -> [Char]

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

12年6月23日土曜日

Page 7: スタートHaskell2 型を信じろ

GHCiの中で型宣言

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

12年6月23日土曜日

Page 8: スタートHaskell2 型を信じろ

引数と返り値の区切

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

詳しくは5章で

12年6月23日土曜日

Page 9: スタートHaskell2 型を信じろ

一般的なHaskellの型(1)

• Int : 整数・有界

• Integer : 整数・有界じゃない

• Float : 単精度浮動小数点数

• Double : 倍精度浮動小数点数

12年6月23日土曜日

Page 10: スタートHaskell2 型を信じろ

一般的なHaskellの型(2)

• Bool :真理値型 (True, False)

• Char : ユニコード文字。Charのリストは文字列

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

12年6月23日土曜日

Page 11: スタートHaskell2 型を信じろ

型変数

Prelude> :t headhead :: [a] -> a

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

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

型変数

12年6月23日土曜日

Page 12: スタートHaskell2 型を信じろ

型変数(2)

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

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

12年6月23日土曜日

Page 13: スタートHaskell2 型を信じろ

型クラス初級講座

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

12年6月23日土曜日

Page 14: スタートHaskell2 型を信じろ

Eq a => ?

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

12年6月23日土曜日

Page 15: スタートHaskell2 型を信じろ

型クラス制約Prelude> :t (==)(==) :: Eq a => a -> a -> Bool

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

違うので注意!

12年6月23日土曜日

Page 16: スタートHaskell2 型を信じろ

型クラス制約Prelude> :t (==)(==) :: Eq a => a -> a -> Bool

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

違うので注意! 詳しくはもっと先で分かる、はず

12年6月23日土曜日

Page 17: スタートHaskell2 型を信じろ

Eq型Eqのインスタンスが実装すべき関数:

==と/=

Prelude> 5 == 5TruePrelude> 5 /= 5FalsePrelude> "foo" == "bar"False

12年6月23日土曜日

Page 18: スタートHaskell2 型を信じろ

型制約の意味

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

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

12年6月23日土曜日

Page 19: スタートHaskell2 型を信じろ

いろんな型クラス

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

12年6月23日土曜日

Page 20: スタートHaskell2 型を信じろ

Ord

•順序づけのある型のための型クラス

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

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

12年6月23日土曜日

Page 21: スタートHaskell2 型を信じろ

compare関数

Prelude> "Abc" >= "Zed"FalsePrelude> "Abc" `compare` "Zed"LTPrelude> 5 >= 2TruePrelude> 5 `compare` 2GT

12年6月23日土曜日

Page 22: スタートHaskell2 型を信じろ

Show型クラス•Show型クラスのインスタンスが型である値は、文字列として表現可能

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

12年6月23日土曜日

Page 23: スタートHaskell2 型を信じろ

Read型クラス

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

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

12年6月23日土曜日

Page 24: スタートHaskell2 型を信じろ

readの例Prelude> read "True" || FalseTruePrelude> read "8.2" + 3.812.0Prelude> read "5" - 23Prelude> read "[1,2,3,4]" ++ [3][1,2,3,4,3]

12年6月23日土曜日

Page 25: スタートHaskell2 型を信じろ

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日土曜日

Page 26: スタートHaskell2 型を信じろ

型注釈Prelude> read "4" :: Int4Prelude> read "4" :: Float4.0Prelude> (read "4" :: Float) * 520.0Prelude> read "[1,2,3,4]" :: [Int][1,2,3,4]Prelude> read "(3, 'a')" :: (Int, Char)(3,'a')

12年6月23日土曜日

Page 27: スタートHaskell2 型を信じろ

型注釈不要な場合

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

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

12年6月23日土曜日

Page 28: スタートHaskell2 型を信じろ

Enum型クラス•「順番に並んだ型」

•要素の値を列挙できる

•レンジの中で使える

•有界じゃないIntegerもEnum型

• C言語的なEnumとは違いますね!

12年6月23日土曜日

Page 29: スタートHaskell2 型を信じろ

Enumの例Prelude> ['a'..'e']

"abcde"Prelude> [LT .. GT][LT,EQ,GT]Prelude> [3 .. 5][3,4,5]Prelude> succ 45Prelude> pred 'Z''Y'

12年6月23日土曜日

Page 30: スタートHaskell2 型を信じろ

Bounded型クラス•上限と下限をもつ

•minBound, maxBound関数

Prelude> minBound :: Int-9223372036854775808Prelude> maxBound :: Char'\1114111'Prelude> maxBound :: BoolTrue

12年6月23日土曜日

Page 31: スタートHaskell2 型を信じろ

多相定数

Prelude> :t minBoundminBound :: Bounded a => a

12年6月23日土曜日

Page 32: スタートHaskell2 型を信じろ

Num型クラス

•数のように振る舞う。

•数の型を調べると:

Prelude> :t 2020 :: Num a => a

12年6月23日土曜日

Page 33: スタートHaskell2 型を信じろ

数は多相定数Prelude> 20 :: Int20Prelude> 20 :: Integer20Prelude> 20 :: Float20.0Prelude> 20 :: Double20.0

12年6月23日土曜日

Page 34: スタートHaskell2 型を信じろ

Numを使う演算子Prelude> :t (*)

(*) :: Num a => a -> a -> a

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

12年6月23日土曜日

Page 35: スタートHaskell2 型を信じろ

Floating型クラス•FloatとDoubleが含まれる

•結果を小数点で表現できないと意味のある計算ができない関数で使う: sin, cos ,sqrt など。

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

12年6月23日土曜日

Page 36: スタートHaskell2 型を信じろ

Integral型クラス

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

• IntとIntegerを含む

12年6月23日土曜日

Page 37: スタートHaskell2 型を信じろ

fromIntegral

Prelude> :t fromIntegralfromIntegral :: (Num b, Integral a) => a -> bPrelude> :t lengthlength :: [a] -> IntPrelude> fromIntegral (length [1,2]) + 3.25.2

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

12年6月23日土曜日

Page 38: スタートHaskell2 型を信じろ

いくつかの注意(1)•ある型は、複数の型クラスのインスタンスになれる

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

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

12年6月23日土曜日

Page 39: スタートHaskell2 型を信じろ

いくつかの注意(2)• あるクラスのインスタンスになるには、他の

クラスのインスタンスになる必要がある事がある。

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

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

12年6月23日土曜日

Page 40: スタートHaskell2 型を信じろ

ありがとうございました

12年6月23日土曜日