2010-08-22 45 views
3

我正在學習一個教程。 (真實世界哈斯克爾)頭部和尾部呼叫空列表帶來異常

而且我有一個有關頭部和尾部的空白列表調用的初學者問題:在GHCi中它返回異常。

直覺上我想我會說他們都應該返回一個空的列表。你能糾正我嗎?爲什麼不 ? (據我記得在OzML左邊或右邊的一個空列表返回零)

我當然還沒有在本教程中介紹過這個主題,但它不是一個錯誤的來源(如果不提供參數)? 我的意思是,如果傳遞給函數的參數列表可能是optionnal,那麼頭部讀取它們可能會導致錯誤?

我只知道GHCi的行爲,我不知道編譯時會發生什麼。

+0

這實際上是「部分功能」更常見問題的特例。 「全部」函數將返回任何參數的結果。部分功能不全;一些參數將返回底部(即錯誤或無限循環)。處理所有語言(所有功能都是全部)正在進行,但不要屏住呼吸。 – 2010-08-22 19:54:55

+0

我不明白「正在進行,但不要屏住呼吸」? 從我現在所做的事情來看,我傾向於更喜歡全局函數而不是部分函數。 – 2010-08-22 20:08:08

+0

@Stephane Rolland:不要等待這種語言成爲現實;)對於大多數情況下,'Maybe a'類型是表達計算的最佳選擇,它可以*返回值。' – Dario 2010-08-22 20:12:42

回答

13

直覺上我認爲他們都應該返回一個空的列表。你能糾正我嗎?爲什麼不 ?

那麼 - head[a] -> a。它返回單個第一個元素;沒有列表。

而當沒有第一個元素像在一個空列表中?那麼返回什麼?您無法創建任何類型的值爲a的值,因此只剩下undefined - 一個錯誤。


and tail?尾巴基本上是沒有第一個元素的列表 - 即比原始元素短一個項目。沒有第一個元素時,你無法堅持這些規律。

當你從一個盒子裏取出一個蘋果時,你不能有相同的盒子(tail [] == []時發生了什麼)。該行爲也必須是undefined


這導致瞭如下結論:

我肯定還沒有本教程中這個話題,但是,這不是它的bug的來源?我的意思是,如果向函數傳遞一個可能是optionnal的參數列表,可能會導致錯誤?

是的,這是一個錯誤的來源,但因爲它允許寫錯誤的代碼。基本上試圖讀取不存在的值的代碼。所以:*永遠不要使用頭部/尾部** - 使用模式匹配。

sum  [] = 0 
sum (x:xs) = x + sum xs 

編譯器可以在所有可能的情況都覆蓋guarantee,值始終定義,它是乾淨多閱讀。

+0

x:xs是的,這是事情被用在OzML(我的意思是左或右)的方式。我對這種寫作方式非常滿意。 thx的答案。 – 2010-08-22 19:40:42

+0

我在類型[a]中加入了安全頭函數 - >也許是 – Zhen 2011-07-06 14:21:34

+0

@ Zhen:當然是。但是,處理'Maybe'通常並不比模式匹配清單簡單,儘管在某些情況下'safeHead'可能肯定有用。 – Dario 2011-07-27 20:06:28