PROGRAMMING IN HASKELL

Slides:



Advertisements
Similar presentations
プログラミング言語論 第3回 BNF 記法について(演習付き) 篠埜 功. 構文の記述 プログラミング言語の構文はどのように定式化できるか? 例1 : for ループの中に for ループが書ける。 for (i=0; i
Advertisements

0章 数学基礎.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
(Rubyistのための) 超音速:ML入門
京都大学情報学研究科 通信情報システム専攻 湯淺研究室 M2 平石 拓
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
プログラミング基礎I(再) 山元進.
プログラミング言語としてのR 情報知能学科 白井 英俊.
Relaxed Dependency Analysis
ソフトウェア基礎科学 授業資料: 論理関係(logical relations)のお話
ファーストイヤー・セミナーⅡ 第8回 データの入力.
最適化ソルバーのための Python言語入門
はじめに 教科書 プログラミングHaskell Graham Hutton (著), 山本 和彦 (翻訳) オーム社、全 232 ページ
型宣言 (Type Declarations)
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
型宣言(Type Declarations)
String - 文字列 2009年10月9日 7ADD2116 佐藤洋輔.
条件式 (Conditional Expressions)
問題 1 キーボードから入力した数の合計を計算するプログラムを 作成せよ。最初に、何個の数を入力するかその数を入力 するようにする。
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
プログラミング言語論 第12回 関数型プログラミング 情報工学科 篠埜 功.
論文紹介: A Second Look at Overloading
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
PROGRAMMING IN HASKELL
第2回.リレーショナルデータベース入門 SQL を用いたテーブルへの行の挿入 SQL 問い合わせの発行と評価結果の確認.
PROGRAMMING IN HASKELL
第2回.リレーショナルデータベース入門 SQL を用いたテーブルへの行の挿入 SQL 問い合わせの発行と評価結果の確認.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
暗黙的に型付けされる構造体の Java言語への導入
電気・機械・情報概論 VBAプログラミング 第2回 2018年7月2日
PROGRAMMING IN HASKELL
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
国立情報学研究所 ソフトウェア研究系 助教授/
 型推論1(単相型) 2007.
3.条件式.
4.リスト,シンボル,文字列.
フロントエンドとバックエンドのインターフェース
情報処理Ⅱ 第2回:2003年10月14日(火).
 型推論3(MLの多相型).
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
統計ソフトウエアRの基礎.
アルゴリズムとプログラミング (Algorithms and Programming)
Type Systems and Programming Languages
国立情報学研究所 ソフトウェア研究系 助教授/
PROGRAMMING IN HASKELL
2006/7/18(通信コース)2006/7/26(情報コース) 住井
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
PROGRAMMING IN HASKELL
~sumii/class/proenb2010/ml5/
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
PROGRAMMING IN HASKELL
第2回.リレーショナルデータベース入門 SQL を用いたテーブルへの行の挿入 SQL 問い合わせの発行と評価結果の確認.
第7章 そろそろ int 以外も使ってみよう! ~データ型 double , bool~
Haskell Programming Language
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
全体ミーティング(9/15) 村田雅之.
プログラミング基礎a 第5回 C言語によるプログラミング入門 配列と文字列
プログラミング入門2 第5回 配列 変数宣言、初期化について
7.集合 7.1 集合とは [集合と要素] 関東の都道府県 群馬県 栃木県 要素 埼玉県 茨城県 東京都 千葉県 神奈川県
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
Presentation transcript:

PROGRAMMING IN HASKELL Chapter 3 - Types and Classes 型とクラス 愛知県立大学 情報科学部 計算機言語論(山本晋一郎・大久保弘崇、2011年)講義資料 オリジナルは http://www.cs.nott.ac.uk/~gmh/book.html を参照のこと

What is a Type? 型とは、関連する値の集まり、またそれにつける名前。 例えば、Haskell の基本型 Bool は、以下の 2 つの真理値を持つ: True False

Type Errors 期待されている型とは異なる型の引数を関数に適用すること 1 は数、False は真理値、+ は 2 つの数を要求する

Types in Haskell 式 e を評価すると型 t の値となるとき、e は型 t を持つといい、以下のように表記する 正しい式(well formed expression)は 1 つの型を持つ。その型はコンパイル時に型推論という手続きにより自動的に決定される。 実行時ではないことに注意

全ての型エラーはコンパイル時に発見される。実行時に型検査をする必要がないので、より安全かつ高速にプログラムを実行できる。 Hugs では :type コマンドで式を評価せずにその型を求めることができる > not False True > :type not False not False :: Bool

Basic Types Haskell は以下のような多数の基本型を持つ: - logical values Bool - logical values Char - single characters Integer - arbitrary-precision integers Float - floating-point numbers String - strings of characters Int - fixed-precision integers

リスト型(List Types) リストは同じ型の値の並び: 一般に: [t] は型 t の値を要素として持つリストの型。 [False,True,False] :: [Bool] [’a’,’b’,’c’,’d’] :: [Char] 一般に: [t] は型 t の値を要素として持つリストの型。 [t] is the type of lists with elements of type t.

要素の型に制約がない。リストのリストも作れる: 注意: 無限長のリストも許される! リスト型に長さの情報は含まれない: [False,True] :: [Bool] [False,True,False] :: [Bool] 要素の型に制約がない。リストのリストも作れる: [[’a’],[’b’,’c’]] :: [[Char]]

タプル型(Tuple Types) タプルは値の(有限個の)組で、各要素の型は異なっていても良い: 一般に: (False,True) :: (Bool,Bool) (False,’a’,True) :: (Bool,Char,Bool) 一般に: (t1, t2, …, tn) は n 項組の型であり、 i 番目の要素は ti 型を持つ(1 ≦ i ≦ n)

注意: タプル型は長さの情報を含んでいる: 要素の型に制約がない: (False,True) :: (Bool,Bool) (False,True,False) :: (Bool,Bool,Bool) 要素の型に制約がない: (’a’,(False,’b’)) :: (Char,(Bool,Char)) (True,[’a’,’b’]) :: (Bool,[Char])

Function Types 関数とは、ある型の値をある型の値に写像(mapping)するもの(テキストでは「写像」ではなく「変換」): not :: Bool  Bool isDigit :: Char  Bool 一般に: t1  t2 は型 t1 の値を型 t2 の値に写像する関数の型。 t1  t2 is the type of functions that map values of type t1 to values of type t2.

矢印  をキーボードで入力するときは -> とする 注意: 矢印  をキーボードで入力するときは -> とする 引数の型、返り値の型に制限はない。例えば、引数や返り値が複数になる関数はリストやタプルを用いる: add :: (Int,Int)  Int add (x,y) = x+y zeroto :: Int  [Int] zeroto n = [0..n]

カリー化された関数(Curried Functions) 複数の引数を取る関数は、関数を返す関数を用いても表せる: add’ :: Int  (Int  Int) add’ x y = x+y add’ は整数 x を取り、関数 add’ x を返す。次に、 この関数は整数 y を取り、x+y の結果を返す。

add と add’ は同じ最終結果を返す。ただし、add は 2 つの引数を同時に受け取り、add’ は 1 つずつ受け取る: 注意: add と add’ は同じ最終結果を返す。ただし、add は 2 つの引数を同時に受け取り、add’ は 1 つずつ受け取る: add :: (Int,Int)  Int add’ :: Int  (Int  Int) Haskell Curry が果たしたこの種の関数に対する研究に敬意を表し、引数を 1 つずつ受け取る関数を カリー化された関数と呼ぶ

3 つ以上の引数を取る関数も、関数を返す関数の入れ子によりカリー化できる: mult :: Int  (Int  (Int  Int)) mult x y z = x*y*z mult は整数 x を取り、関数 mult x を返す、 それは整数 y を取り、関数 mult x y を返す、 それは最後に整数 z を取り、x*y*z の結果を返す

なぜカリー化? カリー化された関数はタプルを取る関数よりも柔軟。 カリー化関数に引数を部分適用して、有益な関数を作れる。 For example: add’ 1 :: Int  Int take 5 :: [Int]  [Int] drop 5 :: [Int]  [Int]

Int  (Int  (Int  Int)) を意味する Currying Conventions カリー化された関数に括弧が付き過ぎるのを避けるために、2 つの規則を導入: 型の矢印  は右結合(associates to the right) Int  Int  Int  Int Int  (Int  (Int  Int)) を意味する

矢印  が右結合なので、自然に関数適用は左結合(associate to the left) mult x y z ((mult x) y) z を意味する 明示的にタプルの使用が要求されない限り、Haskell の関数はカリー化された形で定義する

多相型関数(Polymorphic Functions) 型変数を含む型や式を多相的という polymorphic とは “of many forms” の意味 関数 length は多相関数、型 [a]  Int は多相型 length :: [a]  Int 任意の型 a に対して、関数 length は a 型の要素のリストを引数とし、整数を返す 注意: a がどんな型なのかまったく不明

型変数には、状況に応じて実際の型を当てはめる: 注意: 型変数には、状況に応じて実際の型を当てはめる: > length [False,True] 2 > length [1,2,3,4] 4 a = Bool a = Int 型変数の名前は小文字で始まる。 通常 a, b, c, …という型変数名が用いられる。

標準 Prelude に含まれる多相型関数 例: fst :: (a,b)  a head :: [a]  a take :: Int  [a]  [a] zip :: [a]  [b]  [(a,b)] id :: a  a

多重定義型(値) 数値 3 は整数と浮動小数点の両方と加算できる Bool や Char とは加算できない 数値 3 の型は? Num クラスのインスタンスである任意の型 t に対して、値 3 は型 t を持つ Prelude> :t 3 3 :: (Num t) => t Prelude> :t 3 + 0.0 3 + 0.0 :: (Fractional t) => t Prelude> :t 3 + 0 3 + 0 :: (Num t) => t Prelude> 3 + True ERROR

多重定義型(関数) + は整数にも浮動小数点にも適用可能 Bool や Char には適用できない クラス: 共通のメソッドを備えた型の集合 メソッド: 多重定義された関数 多重定義型(関数) + は整数にも浮動小数点にも適用可能 Bool や Char には適用できない よって、(+) :: a  a  a ではない クラス制約: 型を限定する(ここでは数値型に限定) クラス制約を含む型を多重定義型という (+) :: Num a  a  a  a Num クラスのインスタンスである任意の型 a に対して、 関数 (+) は型 a  a  a を持つ (型の集合 Num の要素である任意の型 a に対して、 …)

多重定義関数(Overloaded Functions) 多相型関数の型がクラス制約を含むとき、多重定義されているという 共通のメソッドを備えた型の集合 sum :: Num a  [a]  a 任意の数値型 a に対して、 関数 sum は a 型の値のリストを引数とし、a 型の値を返す for any numeric type a, sum takes a list of values of type a and returns a value of type a.

制約つきの型変数には、制約を満たす型を当てはめる: 注意: 制約つきの型変数には、制約を満たす型を当てはめる: sum :: Num a  [a]  a > sum [1,2,3] 6 > sum [1.1,2.2,3.3] 6.6 > sum [’a’,’b’,’c’] ERROR a = Int a = Float Char は数値型(Num クラスのインスタンス)ではない

Haskell には多数の型クラスがある: Num - 数値(Numeric)の型クラス Eq - 同等性(Equality)の型クラス Ord - 全順序(Ordered)の型クラス 例: (+) :: Num a  a  a  a (==) :: Eq a  a  a  Bool (<) :: Ord a  a  a  Bool

基本クラス(Eq - 同等クラス) 同等と不等を比較できる値の型の集合 Bool, Char, String, Int, Integer, Float などの基本型 要素が Eq のインスタンスである、リストやタプルも class  Eq a  where   (==), (/=)      :: a  a  Bool    > False == False True > [1, 2] == [1, 2, 3] False > ("ab", False) /= ("ab", False) False

基本クラス(Ord – 順序クラス) Eq クラスのインスタンスであり、 かつ全順序を持つ値の型の集合 Bool, Char, String, Int, Integer, Float などの基本型 要素が Ord のインスタンスである リストやタプルもインスタンスである(辞書式順序) class  (Eq a) => Ord a  where   (<), (<=), (>=), (>)      :: a  a  Bool   max, min                  :: a  a  a > False < True True > [1, 2] < [1, 2, 3] True > ("ab", False) < ("ab", False) False

基本クラス(ShowとRead – 表示と読込可能) Show: show によって文字列に変換可能 Read: read によって文字列を値に変換可能 Bool, Char, String, Int, Integer, Float などの基本型 要素がこのクラスのインスタンスである、リストやタプルも class Show a where     show      :: a  String  class Read a where read :: String  a > show 123 “123” > read “123” :: Int 123

基本クラス(Num – 数値クラス) Eq クラスのインスタンスであり、 以下の6つのメソッドによって計算可能な数値を値としてもつ型の集合 Int, Integer, Float などの基本型 注意: 除算のメソッドを備えていない class  (Eq a, Show a) => Num a  where     (+), (-), (*)  :: a  a  a     negate         :: a  a     abs, signum    :: a  a > negate 3.3 -3.3 > signum (-3) -1

基本クラス(Integral と Fractional) Integral: Num クラスのインスタンス、かつ整数の商と余りを計算するメソッド(div, mod)を備える Fractional: Num クラスのインスタンス、かつ分数の除算と逆数を計算するメソッド(/, recip)を備える > 7 `div` 2 3 > 7 `mod` 2 1 > 7.0 / 2.0 3.5 > recip 2.0 0.5

ヒントとノウハウ(Hints and Tips) Haskell で関数を新しく定義するときは、最初にその型を書いてみると良い プログラムを書いているときに、スクリプト中の全ての関数に関して型を書くのは良い習慣である 多相型の関数を書くとき、その中で数値や同等性や順序を使っているなら、注意深く、必要なクラス制約を用いること

まとめ(3章) 型: 同じ性質を持つ値の集合 コンパイル時の型推論によって型エラーを検出 基本型: Bool, Char, String, Int, Integer, Float リスト型: 同じ型の値の並び [ t ] タプル型: n 項組 (t1, t2, …, tn) カリー化された関数: add’ :: Int  Int  Int 型の矢印  は右結合、関数適用は左結合 多相型: 型変数を含む型 length :: [a]  Int 多重定義型: クラス制約を持つ型 sum :: Num a  [a]  a