Archive for the 'Uncategorized' Category

沖動

Saturday, December 13th, 2008

近來腸胃不適,腹瀉不止,苦不堪言。吃了幾天醫生開的藥,未見多大療效。忽生學中醫的想法。既抱恙在身,不能復如平日讀書,唯可略翻傳記、學述。翻《學海圖南錄:文學史家錢仲聯》,觀錢萼孫如此生猛,大驚,又生考公務員之念。

加了內存

Saturday, December 13th, 2008

加了根512的內存,總內存1G。Mac OS X下風火輪的確少出現了。

聰明的選擇

Saturday, December 13th, 2008

最近大便的時候無意中發現潔雲草紙的slogan換了,改成“聰明的選擇”,原來是“聰明女人選潔雲”。

[Haskell筆記]tuple

Saturday, December 13th, 2008

list的限制是成員的類型必須相同。如果我們有一些不同類型的東西想把它們整合在一起,list就無能為力了。這時,就需要tuple出場了。

tuple可以容納不同類型的成員。和list一樣,成員間用“,”隔開,但首尾用“(”和“)”標識。例如:

(True, 1)
("Hello world", False)
(4, 5, "Six", True, 'b')

上例中,第一個tuple有2個成員,我們稱為2-tuple(也叫pair(對))。第二個有3個成員,稱為3-tuple(也叫triple)。第三個有5個成員,稱之為5-tuple。一般而言,有n個成員的tuple就叫做n-tuple。

和list不同的是,tuple的成員的個數是固定的。如果一個list是由一些Integer組成的,我們再cons一個Integer上去,這個list的類型仍然保持不變,但是pair和triple的類型則完全不同。

數學的集合論中,list和tuple的含義是差不多的。對於一個集合A,從A中抽取一些元素(允許重復取),組成一個有序的list。如果該list含有k個條目,就叫做k-tuple。但在Haskell中,list和tuple則有不同的用處。list在成員的類型上有限制,而tuple則在成員的數目上有限制。

練習

9.1 有一個3-tuple包含三個成員,第1個是4,第2個是"hello",第3個是True。寫出此tuple。

9.2 下面哪些tuple可以成立?

    1. (4, 4)
    2. (4, "hello")
    3. (True, "Blah", "foo")

9.3 我們可以通過cons成員的方式構建list。但沒有與之相應的構建tuple的方法,為什麽?假設有這樣一個函數,如果你cons某個成員到一個tuple上,你會得到什麽?


答案

8.1 1和2不能成立,3可以。

    1. 1:2:3:[]:[] 1、2、3是整數, 而[]是list。
    2. 1:(2:3:[]):4:[] 1和4是整數,2:3:[]是一個包含整數的list。
    3. (1:2:3:[]):[]:[] 1:2:3:[]是一個包含整數的list,而[]是一個空表(單獨一個空表的類型是包含任何類型成員的list,在這裏GHC會將其視為包含整數的list,類型和1:2:3:[]相同。

8.2 都能成立。

    1. [[],[1,2,3],[4,5,6]] 與8.1-3同理。
    2. [[]] 注意這不是一個空表。而是一個包含空表的list。
    3. [[],[]] 包含兩個空表的list。
    4. [[1],[]] 與8.1-3同理。

8.3 可以。比如: [[[1],[2],[3]],[[4],[5],[6]],[[7],[8],[9]]]。

8.4

    1. 包含整數的list和單獨的整數的類型是不一樣的。
    2. 一個是包含整數的list,一個是包含布爾值的list,其類型不同。

[Haskell筆記]list的list

Wednesday, December 10th, 2008

list可以包含任何東西,只要這些東西的類型相同。好的,回味一下這句話:任何東西!所以list也可以包含list!不信可以嘗試一下:

Prelude> let listOfLists = [[1,2],[3,4],[5,6]]
Prelude> listOfLists
[[1,2],[3,4],[5,6]]

Lists of lists can be pretty tricky sometimes, because a list of things does not have the same type as a thing all by itself. Let's sort through these implications with a few exercises:

包含list的list有時比較奧妙。list和list的成員的類型有關,但不相等!具體請通過做下面的習題體會。

練習

8.1 下面哪些list可以成立?哪些不能?為什麽?用cons到空表的形式改寫以下list。

    1. [1,2,3,[]]
    2. [1,[2,3],4]
    3. [[1,2,3],[]]

8.2 下面哪些list可以成立?哪些不能?為什麽?用"[]"和","的形式改寫。

    1. []:[[1,2,3],[4,5,6]]
    2. []:[]
    3. []:[]:[]
    4. [1]:[]:[]

8.3 Haskell允許由包含list的list組成的list嗎?為什麽?

8.4 為何以下list是不合法的?

    1. [[1,2],3,[4,5]]
    2. [[1,2],[True,False]]

答案

7.1

    1. 12:80:[]
    2. 42:"life, universe and everything else":[]
    3. "beer":"sandwiches":[]
    4. 5:4.5:[]
    5. "45":"True":[]
    6. pi:56:[]

7.2 不成立。3是Integer,True, False是Bool。

7.3

Prelude> let cons8 list = 8:list
    1. cons8 [] 輸出 [8]
    2. cons8 [1,2,3] 輸出 [8,1,2,3]
    3. cons8 [True,False] 報錯。錯誤原因同練習7.2。
    4. let foo = cons8 [1,2,3] 沒有屏幕輸出。 但foo這個符號代表[8,1,2,3]。
    5. cons8 foo 輸出 [8,8,1,2,3]

7.4

Prelude> let myCons list thing = thing : list

[Haskell筆記]cons

Monday, December 1st, 2008

很多情況下,我們通過在舊的(已經構造好的)list上增加新成員來構造一個新的list。在Haskell中,我們稱這為把成員cons到list上。我們使用“:”這個控制符來表示這個操作。

Prelude> let numbers = [1,2,3,4]
Prelude> numbers
[1,2,3,4]
Prelude> 0:numbers
[0,1,2,3,4]

cons所得的結果仍然是一個list,所以我們可以繼續cons成員上去。例如:

Prelude> 1:0:numbers
[1,0,1,2,3,4]
Prelude> 2:1:0:numbers
[2,1,0,1,2,3,4]
Prelude> 5:4:3:2:1:0:numbers
[5,4,3,2,1,0,1,2,3,4]

事實上,listnumbers本身(即[1,2,3,4])就可以寫成1:2:3:4:[]的形式。也就是說,所有list都是通過把成員cons到一個空list(用[]表示)上得到的。所以,[成員1,成員2]的表示list的形式并不是不可缺少的,僅僅起到表示起來更方便、看起來更清楚之類的作用,我們把這類表達叫做“語法糖衣”(Syntax Sugar)。

練習

7.1 將6.1中的list改寫成cons到空表的形式。

7.2 3:[True,False]這樣的表達成立嗎?為什麽?

7.3 寫一個函數cons8,將8 cons到輸入的list上。用以下例子測試你的函數:

cons8 []
cons8 [1,2,3]
cons8 [True,False]
let foo = cons8 [1,2,3]
cons8 foo

7.4 寫一個函數,以一個list和一個成員作為輸入,將輸入的成員cons到輸入的list上。


答案

    1. [12, 80]成立。12和80都是Integer。
    2. [42, "life, universe and everything else"]不成立。一個是Integer,一個是String。
    3. ["beer", "sandwiches"]成立。都是String。
    4. [5, 4.5]成立。都是Double。(在這種情況下,Haskell能判斷出5應當作為Double看待,而不是Integer。)
    5. ["45", "True"]成立。都是String。
    6. [pi, 56]成立。都是Double。(pi是一個符號,符號的類型由其代表的值決定。)

[Haskell筆記]list

Sunday, November 30th, 2008

函數是構建Haskell程序的兩大基本部件之一,另一個則是list(列表)。

list的表示方法很簡單,首先列舉list的各成員,然後以“,”分隔各成員,最後用“[”和“]”標記list的開頭和結尾。比如,[1,2,3,4]。

為了便於以後的稱說,我們通常給list“起個名字”(指定一個符號代表它),例如:

Prelude> let numbers = [1,2,3,4]
Prelude> let truths  = [True, False, False]
Prelude> let strings = ["here", "are", "some", "strings"]

特別要當心的是,list中的成員必須擁有相同的類型。在上面的三個例子中,numberslist的成員都是Integer(整數),truthslist的成員都是Bool(布爾值),stringslist的成員都是String(字符串)(字符串用""括起來)。不同類型的成員無法在一個list中共存。比如,如果輸入:

Prelude> let mixed = [1,True]

GHCi就會報錯:

<interactive>:1:13:
    No instance for (Num Bool)
      arising from the literal `1' at <interactive>:1:13
    Possible fix: add an instance declaration for (Num Bool)
    In the expression: 1
    In the expression: [1, True]
    In the definition of `mixed': mixed = [1, True]

這是因為1的類型是Integer,而True的類型是Bool,兩者類型不同。

練習

6.1 以下哪些list可以成立,哪些不可以,為什麽?

    1. [12, 80]
    2. [42, "life, universe and everything else"]
    3. ["beer", "sandwiches"]
    4. [5, 4.5]
    5. ["45", "True"]
    6. [pi, 56]

答案

5.1 25

Prelude> areaSquare 5
25

5.2

Prelude> let areaCircle r = pi * r ^ 2
Prelude> let volCylinder r h = areaCircle r * h

5.3

Prelude> let areaRect l w = l * w
Prelude> let areaSquare s = areaRect s s
Prelude> let areaCircle r = pi * r ^ 2
Prelude> let diffOfCnS r = areaCircle r - areaSquare r

[Haskell筆記]函數定義中使用函數

Thursday, November 27th, 2008

定義函數時,可以使用其它已經定義好的函數。比如,求正方形的面積。正方形是矩形的一個特例,所以定義求正方形面積的函數時,可以利用求矩形面積的函數。

Prelude> let areaRect l w = l * w
Prelude> let areaSquare s = areaRect s s

練習

5.1 利用areaSquare求邊長為5的正方形的面積。
5.2 寫一個求圓柱體體積的函數(利用求圓面積的函數)
5.3 寫一個函數解決以下問題:給定圓的半徑,且已知有一正方形的邊長和該半徑相等,求該圓與該正方形面積之差。


答案

4.1 areaTriangle b h = (b * h) / 2

4.2 areaCube l w h = l * w * h

[Haskell筆記]多元函數

Tuesday, November 18th, 2008

上次我們討論了求圓面積的函數,即

f r = pi * r ^ 2

這裏f代表function(函數),表達的信息量很有限。如果我們的程序裏有很多這樣的函數,就很不方便。你得讀完整行纔知道這是一個求圓的函數。為了增加可讀性(或者說方便偷懶,不用讀完函數的整個定義就知道函數是幹啥的),寫成類似以下的形式好一些:

areaCycle r = pi * r ^ 2

好了,求了圓的面積,求了圓的周長(練習3.1),下面我們來求矩形的面積areaRect。和圓不一樣,長方形的面積取決於長和寬。那該怎麽寫呢?很簡單,以空格隔開,依次列出就可以了。

Prelude> let areaRect l w = l * w

那麽,長為5,寬為10的矩形的面積為:

Prelude> areaRect 5 10
50

練習

4.1 寫一個求三角形面積的函數。
4.2 寫一個求長方體體積的函數。


答案:

3.1

g r = 2 * pi * r

拼音有的时候会起干扰作用

Tuesday, November 18th, 2008

例子很多,只举一个,xiong,看上去是齐齿呼,其实是撮口呼。