天天看點

《Two Dozen Short Lessons in Haskell》學習(十六)- Definitions with Alternatives

 《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"

這個函數可以用于去掉文章中不文雅的詞。