mpfi20080910

16
Haskell 耀(Beginning) (Examples as Introduction) (Syntax) (Sorting) 色與(Features and Advantage) (Program Gluing) (Program Derivation) (Bibliography) 語言Haskell 耀[email protected] September 10, 2008 1 / 16

Transcript of mpfi20080910

Page 1: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

函數程式語言: Haskell

黃耀賢

[email protected]微程式技術研討會

September 10, 2008

1 / 16

Page 2: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

Outline

1 起頭(Beginning)

2 示範介紹(Examples as Introduction)語法(Syntax)排序(Sorting)

3 特色與優點(Features and Advantage)

4 程式黏合(Program Gluing)程式推演(Program Derivation)

5 參考文獻(Bibliography)

2 / 16

Page 3: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

sum Function

• sum :: [Int] -> Intsum [] = 0sum (x:xs) = x + sum xs

• int sum(int* a, int n) {int i, r = 0;for (i=n; i>0; i–)

r += *(a+i-1);return r;

}

3 / 16

Page 4: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

len Function

• len :: [a] -> Intlen [] = 0len (x:xs) = 1 + len xs

• int len(int* a) {return (sizeof a) / sizeof(a[0]);

}

4 / 16

Page 5: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

Say “Hello, world!”

1 執行 ”Hello, world!”

2 執行 print ”Hello, world!”print :: (Show a) => a -> IO ()

3 在已載入包含 main = print ”Hello, world!” 函數的指令介面中,執行 main 函數。main :: IO ()

5 / 16

Page 6: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

函數程式的執行• sum [1,2,3,4]

= { sum (x:xs) = x + sum xs }1 + sum [2,3,4]

= { sum (x:xs) = x + sum xs }1 + (2 + sum [3,4])

= { sum (x:xs) = x + sum xs }1 + (2 + (3 + sum [4]))

= { sum (x:xs) = x + sum xs }1 + (2 + (3 + (4 + sum [])))

= { sum [] = 0 }1 + (2 + (3 + (4 + 0)))

= { + 的定義 }1 + (2 + (3 + 4))

= { + 的定義 }1 + (2 + 7)

= { + 的定義 }1 + 9

= { + 的定義 }

10 { Normal Form }

6 / 16

Page 7: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

語法:函數簽章(function

signature)

• C++ 函數簽章:int main(int argc, char* argv[])

char* strcat(char* s1, const char* s2)

double area(double, double); double

area(double)

• Haskell 函數簽章:sum :: [Int] -> Int

square :: Int -> Int

strcat :: [Char] -> [Char]

anycat :: [a] -> [a]

7 / 16

Page 8: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

語法:依位置決定(Juxaposition)

• 執行

a b c · · ·意味 a 為函數, b c · · · 為參數。

• sum [1,2,3,4,5,6,7,8,9,10]len [1,2,3,4,5,6,7,8,9,10]

• map’ :: (a -> b) -> [a] -> [b]map’ f [] = []map’ f (x:xs) = f x : map’ f xstoString :: Int -> [Char]toString n

| n < 10 = [intToDigit n]| otherwise = toString (div n 10) ++ [intToDigit

(mod n 10)]maptest = map’ f [1,2,3]

where f x = ”Hello, ” ++ toString x

8 / 16

Page 9: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

型態檢查

• len :: [a] -> Intlen [] = 0len (x:xs) = 1 + len xs

• 0 :: Int

[] :: [a]

• len [] :: Int

• len :: [a] -> Int

• len xs :: Int 假設 xs :: [a]

• 1 + len xs :: Int

• (x:xs) :: [a] 假設 x :: a 且 xs :: [a]

• len (x:xs) :: Int 假設 (x:xs) :: [a]

9 / 16

Page 10: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

用 C++ 排序• void qsort(int* a, int lo, int hi) {

if (lo < hi) {int l = lo, h = hi - 1, p = a[hi];do {

while ((l < h) && (a[l] <= p)) l = l + 1;while ((h > l) && (a[h] >= p)) h = h - 1;if (l < h) swap(a[l], a[h]);

} while (l < h);swap(a[l], a[hi]);qsort(a, lo, l-1); qsort(a, l+1, hi);

}}

• void show(int* a, int n) {int i;cout << ’[’;for (i=0; i<n; i++)

if (i == n-1) cout << a[i];else cout << a[i] << ’,’;

cout << ’]’ << endl;}

10 / 16

Page 11: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

用 Haskell 排序

• qsort :: [Int] -> [Int]qsort [] = []qsort (x:xs) = qsort lpart xs ++ [x] ++ qsort rpart xs

where lpart xs = filter (<x) xsrpart xs = filter (>=x) xs

• 用 Haskell 寫泡沫排序法:需要嗎?

11 / 16

Page 12: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

函數語言的優點

1 沒有這些毛病:

• 沒有指定命令(assignment):「變數」值不會改變。• 沒有副作用(side-effect):沒有狀態 / 不受狀態影響。• 沒有特定執行順序:任何時候都能執行 / 可用 lazy

evaluation 和 call-by-name 。• 參考透明化(referential transparency):程式可以用數學方式追蹤,且追蹤能比一般程式語言容易。

2 產能:程式寫起來比較短。 (?)

3 函數黏合:可將程式共通部份取出,做通用函數,使功

能重用。

4 高階函數:函數與函數的組合構成強大功能。

12 / 16

Page 13: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

函數黏合• nonsense :: [Int] -> Int

nonsense [] = []

nonsense (x:xs) = x : nonsense xs• sum :: [Int] -> Int

sum [] = 0

sum (x:xs) = x + sum xs

• 改寫:

nonsense = fold (:) []sum = fold (+) 0

• fold 的定義:fold :: (a -> b -> b) -> b -> [a] -> b

fold f e (x:xs) = f x (fold f e xs)• len :: [a] -> Int

len [] = 0

len (x:xs) = 1 + len xs

• 改寫: len = fold (\ x -> \ y -> 1 + y) 0• λ expression: λx .λy .1 + y

13 / 16

Page 14: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

程式證明

• 證明:已知 a1, . . . , an ,求 a21 + . . . + a

2n,化簡

sumsq = sum.map square 。

• sumsq []= { sumsq 的定義 } (sum . map square) []= { 函數結合的定義 } sum (map square [])= { map 的定義 } sum []= { sum 的定義 } 0

• sumsq (x:xs)= { sumsq 的定義 } sum (map square (x:xs))= { map 的定義 } sum (square x : map square xs)= { sum 的定義 } square x + sum (map square xs)

= { sumsq 的定義 } square x + sumsq xs

• sumsq :: [Int] -> Intsumsq [] = 0

sumsq (x:xs) = square x + sumsq xs

14 / 16

Page 15: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

程式優化

• steep :: [Int] -> Boolsteep [] = Truesteep (x:xs) = steep xs ∧ x < sum xs

• steepsum xs = (steep xs, sum xs)• steepsum (x:xs)

= { steepsum 的定義 }(steep (x:xs), sum (x:xs))

= { steep 與 sum 的定義 }(steep xs ∧ x < sum xs, x + sum xs)

= { 抽取子程序部份 }let (b, s) = (steep xs, sum xs)

in (b ∧ x < s, x + s)

• steepsum :: [Int] -> Boolsteepsum [] = Truesteepsum (x:xs) = let (b, s) = (steep xs, sum xs)

in (b ∧ x < s, x + s)

15 / 16

Page 16: mpfi20080910

函數程式語言: Haskell

黃耀賢

起頭(Beginning)

示範介紹(ExamplesasIntroduction)

語法(Syntax)

排序(Sorting)

特色與優點(FeaturesandAdvantage)

程式黏合(ProgramGluing)

程式推演(ProgramDerivation)

參考文

獻(Bibliography)

參考文獻

1 John Hughes. Why Functional Programming Matters.Computer Journal, 32(2), 1989.

2 Henk Barendregt and Erik Barendsen. Introduction toLambda Calculus. Mar 2000.ftp://ftp.cs.kun.nl/pub/CompMath.Found/lambda.pdf

16 / 16