裘宗燕把蔡学鏞批了一通

January 5th, 2009 Uncategorized

蔡学鏞的思考函数编程(一)(二)是廣為流傳的兩篇文章。《程序員》2008年第7期轉載了後,2008年8期就發了裘宗燕的《關於“思考函數式編程”幾點注記》,就formal、calculus的翻譯,計算機器的歷史,常規語言中作函數式編程的有限性,函數式與命令式語言和棧和堆的關系,批了蔡學鏞一通。(原文是“我覺得有幾個問題需要澄清。”)

wps

January 5th, 2009 Uncategorized

發現打印店的Microsoft Word換成WPS了。Microsoft的“黑屏”的效果比我想像的要大。

拼寫檢查依賴

January 5th, 2009 Uncategorized

無論是vim還是firefox下都有拼寫檢查。我發現我開始比較嚴重地依賴拼寫檢查了,很多單詞都只是記得個大概,剛好夠拼寫檢查猜出。一旦脫離電腦在紙上寫,就感覺怪怪的,很多單詞都似是而非,心裏感覺空蕩蕩的。

[Haskell筆記]let/in語句

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

[Haskell筆記]復合函數

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版所載,“胡先生豆腐”實為在胡光煒在南京馬祥興菜館就餐時常點的一道菜。此菜用雞肝、蝦仁、筍尖等鮮嫩配料烹制而成。因胡光煒大加贊譽,遂有此名。

[Haskell筆記]case語句

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

git的index

December 22nd, 2008 Uncategorized

一直是git commit -a的,也沒多想。嘗試hg後開始想為何git要這樣設計?發現自己忽略了git的一個重要的概念:index或者staging area。

兩篇談git的index的很有意思的文章:

Git's Killer Feature

Limbo: Why users are more error-prone with git than other VCSes

ssmtp連aliases也不支持

December 21st, 2008 Uncategorized

從這點上看,還是nullmailer方便些。雖然SMTP STARTTLS、 SMTP AUTH CRAM-MD5 之類的不支持。

cgit powerpc deb

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.