スタートhaskell2 型を信じろ
TRANSCRIPT
すごいHaskell本2章: 型を信じろ!
小嶋智 @skoji
12年6月23日土曜日
• Haskell学びはじめて1ヶ月なので
•間違いあったら遠慮無く突っ込んでください
12年6月23日土曜日
強力な型システム•型に関するエラーはコンパイル時に検知できる
• (型の自動変換はない)
•型推論がある
•型システムをしっかり理解しよう
12年6月23日土曜日
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日土曜日
GHCiで型を調べる(2)
Prelude> let removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]Prelude> :t removeNonUppercaseremoveNonUppercase :: [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 addThreeaddThree :: Int -> Int -> Int -> IntPrelude>
12年6月23日土曜日
引数と返り値の区切
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日土曜日
一般的なHaskellの型(1)
• Int : 整数・有界
• Integer : 整数・有界じゃない
• Float : 単精度浮動小数点数
• Double : 倍精度浮動小数点数
12年6月23日土曜日
一般的なHaskellの型(2)
• Bool :真理値型 (True, False)
• Char : ユニコード文字。Charのリストは文字列
•タプル: 要素数と要素の型で型が決まる
12年6月23日土曜日
型変数
Prelude> :t headhead :: [a] -> a
ちょっとGenericsぽいけどもっと強力。
こういうのを「多相的関数」という
型変数
12年6月23日土曜日
型変数(2)
Prelude> :t fstfst :: (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 == 5TruePrelude> 5 /= 5FalsePrelude> "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"FalsePrelude> "Abc" `compare` "Zed"LTPrelude> 5 >= 2TruePrelude> 5 `compare` 2GT
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 readread :: Read a => String -> a
12年6月23日土曜日
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日土曜日
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" :: 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日土曜日
型注釈不要な場合
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 45Prelude> pred 'Z''Y'
12年6月23日土曜日
Bounded型クラス•上限と下限をもつ
•minBound, maxBound関数
Prelude> minBound :: Int-9223372036854775808Prelude> maxBound :: Char'\1114111'Prelude> maxBound :: BoolTrue
12年6月23日土曜日
多相定数
Prelude> :t minBoundminBound :: Bounded a => a
12年6月23日土曜日
Num型クラス
•数のように振る舞う。
•数の型を調べると:
Prelude> :t 2020 :: Num a => a
12年6月23日土曜日
数は多相定数Prelude> 20 :: Int20Prelude> 20 :: Integer20Prelude> 20 :: Float20.0Prelude> 20 :: Double20.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 sinsin :: Floating a => a -> a
12年6月23日土曜日
Integral型クラス
•Numは実数を含むが、Integralは整数全体のみが含まれる。
• IntとIntegerを含む
12年6月23日土曜日
fromIntegral
Prelude> :t fromIntegralfromIntegral :: (Num b, Integral a) => a -> bPrelude> :t lengthlength :: [a] -> IntPrelude> fromIntegral (length [1,2]) + 3.25.2
•整数と浮動小数点数を一緒に扱う時便利
12年6月23日土曜日
いくつかの注意(1)•ある型は、複数の型クラスのインスタンスになれる
•型クラスは複数の型をインスタンスにもてる
•例: CharはEqとOrdとその他いろいろのインスタンス
12年6月23日土曜日
いくつかの注意(2)• あるクラスのインスタンスになるには、他の
クラスのインスタンスになる必要がある事がある。
• 例: Ordのインスタンスになるには、さきにEqのインスタンスになる必要がある
• 「順序づけられるなら(Ord)、比べることもできるはず(Eq)」
12年6月23日土曜日
ありがとうございました
12年6月23日土曜日