2009-10-22 41 views
4

我是Haskell的新手,所以我既天真又好奇。有關簡單因子函數的機制的解釋

有一個階乘函數的定義:

factorial n = product [1..n] 

我天真地明白這一點爲:使每一批產品1和n之間。那麼,爲什麼

factorial 0 

返回1(這是很好的結果,據我的數學是不是太生鏽)?

謝謝

回答

13

這是因爲如何product定義,是這樣的:

product []  = 1 
product (n:ns) = n * product ns 

或等價

product = foldr (*) 1 
通過重要的功能 foldr

foldr f z []  = z 
foldr f z (x:xs) = f x (foldr f z xs) 

閱讀上折here。但基本上,任何遞歸都必須有一個基本情況,並且product的基本情況(在空列表中)顯然必須是1.

+0

是的,明顯遺漏的基本案例讓我有點困惑,現在更清楚了,謝謝。 – 2009-10-22 15:17:21

+0

@發生了,不客氣! – 2009-10-22 15:31:52

-2

不知道我明白你的問題,你問的是如何編寫這樣一個函數?

只是作爲一個練習,您可以使用模式匹配接近這樣的:

factorial :: Int->Int 
factorial 0 = 1 
factorial n = product [1..n] 

第一行是函數的聲明/簽名類型。第二行是定義函數的方程式 - Haskell模式匹配將實際運行時參數與適合的方程式匹配。

當然,正如其他人指出的,產品功能正確地爲您處理零案件。

4

傳統上定義空列表的所有元素的乘積爲1 ,正如傳統的那樣,將空列表的所有元素的總和定義爲0.這樣,

(product list1) * (product list2) == product (list1 ++ list2) 

以及其他方便的屬性。

此外,你的記憶是正確的,0!定義爲1.這也有許多方便的屬性,包括與gamma function中的階乘定義一致。

+0

謝謝,今晚我會做我的數學作業! =) – 2009-10-22 15:18:32

5

關於的故事空的產品是漫長而有趣的。

現在我舉一個例子,當空產品約定可以產生一個令人驚訝的,不直觀的結果。

如何定義概念素數,無需明確排除1?看起來很不美觀,說「除了這個和那個以外,總理是這樣那樣的」。素數的概念可以用一些方便的定義來定義,它可以用「自然」,「自動」的方式排除1,而沒有明確提到排除?

讓我們來試試這個方法:

讓我們把一個自然數Ç複合,當且僅當Ç可以寫成的一些一個 產品,...,⋅a n自然數,因此它們全部必須不同於c

讓我們把一個自然數p素,當且僅當p不能寫任何的產物一個ň自然數分別從p不同。

讓我們測試該方法是否是任何良好:

6 = 6⋅1
            3⋅2
6是複合材料,該事實通過以下因式分解目擊:6可以寫成乘積3⋅2,或換句話說,⟨3,2⟩序列的乘積,記爲Π⟨3,2⟩。

到現在爲止,我們的新方法是O.K.

5 = 5⋅1
            1⋅5
5是素數,沒有序列⟨一個 ,... 一個Ñ

  • 其所有成員a ,...一個ñ將從5
  • 不同,但產品本身,Π⟨一個 ,... 一個Ñ⟩將等於5.

到目前爲止,我們的新方法是可以的

現在讓我們來研究1:

1 =Π⟨⟩,

空的產品是一個很好的見證,有了它,1個滿足的是一個複合定義(!!!)誰是證人?見證分解在哪裏?它不是空產品Π⟨⟩,即空序列product的產品。

  • Π⟨⟩等於1個
  • 空產物Π⟨⟩的所有因素,即,空序列的成員⟨⟩滿足它們中的每1不同:僅僅是因爲空序列⟨⟩不根本沒有任何成員,因此它的成員都不能等於1.(這個論證只是一個vacuous truth, with members of the empty set)。

因此1是一個複合(具有Π⟨⟩空產品的平凡分解)。

因此,根據定義,1被自然且自動地排除在外。我們達到了我們的目標。爲此,我們利用了有關空產品爲1的約定。

一些缺點:雖然我們成功地排除了1是素數,但同時0「滑入」:0成爲素數(至少在零因子自由環中,如自然數)。雖然這個奇怪的東西使得一些定理在形式上更加簡潔(哥德巴赫猜想,算術基本定理),但我不能忍受它不是缺點。

一個更大的缺點,一些算術的概念似乎變得站不住腳,這種新方法。在任何情況下,我只想證明將空產品定義爲1可以使形式化的不直觀的事情(這不一定是一個問題,集合理論充斥着不直觀的東西,參見how to produce gold for free),但同時,它可以在某些情況下提供有用的力量。