《Two Dozen Short Lessons in Haskell》(Copyright © 1995, 1996, 1997 by Rex Page,有人翻譯為Haskell二十四學時教程,該書如果不用于赢利,可以任意釋出,但需要保留他們的copyright)這本書是學習 Haskell的一套練習冊,共有2本,一本是問題,一本是答案,分為24個章節。在這個站點有PDF檔案。幾年前剛開始學習Haskell的時候,感覺前幾章還可以看下去,後面的内容越來越難以了解。現在對函數式程式設計有了一些了解後,再來看這些題,許多内容變得簡單起來了。
初學Haskell之前一定要記住:
把你以前學習面向過程的正常的程式設計語言,如Pascal、C、Fortran等等統統忘在腦後,函數式程式設計完全是不一樣的程式設計模型,用以前的術語和思維來了解函數式程式設計裡的概念,隻會讓你困惑和迷茫,會嚴重地影響你的學習進度。
這個學習材料内容太多,想把整書全面翻譯下來非常困難,隻有通過練習題将一些知識點串起來,詳細學習Haskell還是先看其它一些入門書籍吧,這本書配套着學學還是不錯的。
第16章 帶條件分支的函數定義
1 Guards in function definitions
a hide the internal details of the function from other software components
b remove some of the elements from the sequence
c select the formula that delivers the value of the function
d protect the function from damage by cosmic rays
2 The formula map reverse ["able", "was", "I"] delivers the value
a ["I", "saw", "elba"]
b ["elba", "saw", "I"]
c ["I", "was", "able"]
d ["able", "was", "I", "not"]
3 The formula map f xs delivers the value
a f x
b [f x | x <- xs]
c f xs
d [f xs]
4 Which of the following formulas is equivalent to the formula [g x y | y <- ys] ?
a (map . g x) ys
b (map g x) ys
c map (g x y) ys
d map (g x) ys
5 The following function delivers
HASKELL DEFINITION • h xs
HASKELL DEFINITION • | xs == reverse xs = "yes"
HASKELL DEFINITION • | otherwise = "no"
a "yes", unless xs is reversed
b "yes" if its argument is a palindrome, "no" if it’s not
c "no" if xs is not reversed
d "yes" if its argument is written backwards, "no" if it’s not
6 The following function
HASKELL DEFINITION • s x
HASKELL DEFINITION • | x < 0 = -1
HASKELL DEFINITION • | x == 0 = 0
HASKELL DEFINITION • | x > 0 = 1
a the value of its argument
b the negative of its argument
c a code indicating whether its argument is a number or not
d a code indicating whether its argument is positive, negative, or zero
7 Assuming the following definitions, which of the following functions puts in sequence of x’s in place of all occurrences of a given word in a given sequence of words?
HASKELL DEFINITION • rep n x = [ x | k <- [1 . . n]]
HASKELL DEFINITION • replaceWord badWord word
HASKELL DEFINITION • | badWord == word = rep (length badWord) ’x’
HASKELL DEFINITION • | otherwise = word
a censor badWord = map (replaceWord badWord)
b censor badWord = map . replaceWord badWord
c censor badWord = replaceWord badWord . map
d censor badWord = map badWord . replaceWord
=========================================================
答
案
在
下
面
=========================================================
1 c
在函數定義裡還可以有分支,當滿足某種條件時,用一種定義,當滿足另外的條件時,用另外一套定義。有點像C語言中的switch語句。
f x
| x > 0 = 1
| otherwise = -1
2 b
這道題容易做錯。
先想想reverse ["able", "was", "I"]的結果是什麼就不容易做錯了。
以前提到過reverse函數的意思是把一個清單中的元素倒序排列, ["able", "was", "I"]這個裡面有三個元素,倒過來就是[“I”, "was", "able"]。
那麼map reverse函數的功能就可以這樣描述了:把一個清單xsFather中的每個元素xsChild(本身還是一個清單)裡的内容倒序。上例中xsFather就是["able", "was", "I"],第一個元素是xsChild就是“able”,倒過來就是"elba",這樣map函數的意思也就清楚了,就是把reverse函數都作用于每個元素。
3 b
這裡就是map函數的定義:
map f xs = [f x | x <- xs]
每一個參數f本身也是個函數,它要作用于後面xs裡的每個元素x上,即f x。
第二個參數xs是一個清單,實際上就是把函數f周遊作用于xs中的元素上。
4 d
根據柯裡函數的定義,g x也是一個函數,不妨記為h,那麼
map (g x) ys = map h ys = [ h y | y <- ys]
這樣應該好了解一些了。
對于柯裡函數搞不懂的,需要認真學習高階函數和不全函數等概念,一開始挺難了解的:-(
參見:《Two Dozen Short Lessons in Haskell》學習(九)- Types of Curried Forms and Higher Order Functions
5 b
就是一個回文序列的判斷函數,如果是回文,就傳回"yes",否則傳回"no"
h xs
| (xs == reverse xs) = "yes" -- 當一個序列如果等于它的反序時
| otherwise = "no"
加上括号就好了解一些了。
在haskell中這個豎線就叫guard,注意縮進。每一條豎線後面跟着一個布爾表達式,當它滿足時就用=後面的定義,不滿足時,繼續判斷下一個guard條件。
6 d
這個很簡單,就是通常的求一個數的正負符号的函數。
7 a
rep n x = [ x | k <- [1 . . n]] 這個函數可以把x重複n次,這裡的x并沒有說是什麼類型。
例如:rep 3 2 就等于[2,2,2]
rep 3 '2'就是['2', '2', '2'],即"222"
guard條件是: | badWord == word
緊接的定義是: = rep (length badWord) ’x’
就是把badWord全換為字元'x'
replaceWord "fuucck" "fuucck"就等于"xxxxxx"
這個函數可以用于去掉文章中不文雅的詞。