裘宗燕把蔡学鏞批了一通
January 5th, 2009
Uncategorized
January 5th, 2009
Uncategorized
無論是vim還是firefox下都有拼寫檢查。我發現我開始比較嚴重地依賴拼寫檢查了,很多單詞都只是記得個大概,剛好夠拼寫檢查猜出。一旦脫離電腦在紙上寫,就感覺怪怪的,很多單詞都似是而非,心裏感覺空蕩蕩的。
January 5th, 2009
Uncategorized
復合函數有助於避免重復。比如,我們有一個求一元二次方程的函數(假定方程有實根):
roots a b c =
((-b + sqrt(b*b - 4*a*c)) / (2*a),
(-b - sqrt(b*b - 4*a*c)) / (2*a))
sqrt(b*b - 4*a*c)重復出現了,使得整個定義顯得很冗長。我們可以利用復合函數來改善這個情況:
delta a b c = sqrt(b*b - 4*a*c) roots' a b u = ((-b + u) / (2*a), (-b - u) / (2*a)) roots a b c = roots' a b (delta a b c)
不過,這種情況,使用let/in語句能使代碼更緊湊:
roots a b c =
let delta = sqrt (b*b - 4*a*c)
in ((-b + delta) / (2*a),
(-b - delta) / (2*a))
使用let/in還有一個好處,就是let語句中定義的符號,如上例的delta,只在in語句後有用。也就是說,定義的delta只在roots函數內部有用。其它函數看不到roots內部定義的delta。當程序比較大時,這種局部綁定可以有效避免符號雜亂的情況。
練習
16.1 下面是一個輸出一元二次函數與x軸交點及頂點坐標的函數,試補全之:
f a b c =
let delta = sqrt (b*b - 4*a*c)
v =
in [(v + delta / (2*a),0),
( ,0),
(v,delta/(-4*a))]
答案
15.1
vol s h = s * h areaCircle r = pi * r ^ 2 areaRect a b = a * b
Prelude> volCircle = vol (areaCircle r) h Prelude> volRect = vol (areaRect a b) h
January 2nd, 2009
Uncategorized
復合函數是指使用一個函數的輸出作為另一個函數的輸入。數學中,符合函數是這麽寫的:
f∘g(x) = f(g(x))
相應的,Haskell中復合函數也有兩種寫法:
(f . g) x
或
f (g x)
練習
15.1 定義求柱體體積的函數為底面積乘高及求圓面積函數、求矩形面積函數。分別用兩種方式寫出利用復合函數求圓柱體及立方體體積的表達式。
答案
14.1 無論輸入的是什麽數字,輸出均為-1。因為
myCase _ = -1
排在最前,覆蓋了後面的語句。要避免這一情況,需要將這一句放在最後。事實上,如果沒有這麽放在最後,GHC會警告:
Warning: Pattern match(es) are overlapped
In the definition of `myCase':
myCase 0 = ...
myCase 1 = ...
myCase 2 = ...
December 23rd, 2008
Uncategorized
胡光煒哲嗣胡令暉在《回憶我的父親--胡小石》一文中寫道:“當今八十八歲的廚王胡長齡最近還在菜譜書上找到我父親解放前自己所創的一道菜的記載--‘胡先生豆腐’。”(《學苑奇峰--文史學家胡小石》,南京大學出版社2000年4月,ISBN 7-305-03512-2, 118頁)
不過,據2006年5月28日的《江南時報》8版所載,“胡先生豆腐”實為在胡光煒在南京馬祥興菜館就餐時常點的一道菜。此菜用雞肝、蝦仁、筍尖等鮮嫩配料烹制而成。因胡光煒大加贊譽,遂有此名。
December 23rd, 2008
Uncategorized
不知道你是否完成了練習13.2中的函數?是否覺得函數的定義過於冗長了?的確,這種情況用if/then來定義不是很方便。case語句更適合這類情況。
用case語句重寫的13.2中的函數:
myCase x =
case x of
0 -> 1
1 -> 5
2 -> 2
_ -> -1
其中,_匹配所有情況。
case語句還有一種一段一段的寫法,比如,和上述函數等價的寫法:
myCase 0 = 1 myCase 1 = 5 myCase 2 = 2 myCase _ = -1
練習
14.1 如果將myCase改成以下定義,會出現什麽情況,為什麽?
myCase _ = -1 myCase 0 = 1 myCase 1 = 5 myCase 2 = 2
答案
13.1 輸入為5時,mySignum判斷5不小於0,故返回else if後面的語句,判斷5大於0, 故返回1。輸入為0時,mySignum判斷0不小於0,故返回else if後面的語句,判斷0不大於0, 故返回0。輸入為-1時,mySignum判斷-1小於0,故返回-1。
13.2
myCase x =
if x == 0
then 1
else if x == 1
then 5
else if x == 2
then 2
else -1
December 22nd, 2008
Uncategorized
一直是git commit -a的,也沒多想。嘗試hg後開始想為何git要這樣設計?發現自己忽略了git的一個重要的概念:index或者staging area。
兩篇談git的index的很有意思的文章:
Limbo: Why users are more error-prone with git than other VCSes
December 21st, 2008
Uncategorized
從這點上看,還是nullmailer方便些。雖然SMTP STARTTLS、 SMTP AUTH CRAM-MD5 之類的不支持。
December 21st, 2008
Uncategorized
Currently there is no cgit deb in the official Debian software repository. If you're using i386 or amd64, you get can the package from stbuehler's server. If you're using powerpc, I've complied a deb package for powerpc.