如果我們看看你的定義,
exists :: (t -> Bool) -> [t] -> Bool
exists f a []=error
exists f a (x:xs)
|if x∈f a =True
|otherwise= x:f a xs
我們看到你的類型是
exists :: (t -> Bool) -> [t] -> Bool
所以exists
必須帶兩個參數,一個類型爲(t -> Bool)
的謂詞函數和一個類型爲[t]
的列表。它返回一個Bool
。根據我們的規範意圖,這看起來沒問題。
讓我們看看你的條件的第一行:
exists f a [] = error
此功能突然有三個參數。 f
和空列表構造函數[]
看起來沒問題,但在類型說明中未提及a
。因此,我們刪除它:
exists f [] = error
現在,返回的error
不是布爾值。但規範說它一定是。讓我們假設我們要求exists (<2) []
。那麼問題的自然答案是True
或False
?或換言之,是否有任何元素x in []
滿足謂詞f x
?
到下一行,
exists f a (x:xs)
|if x∈f a =True
|otherwise= x:f a xs
我們瞭解到,a
具有由類型規範中去,所以讓我們修剪它。由於我們現在對a
自然不喜歡,所以爲什麼不在發生的任何地方修剪它。此外,由於if
會產生一個語法錯誤,讓我們擺脫這種過於自我:
exists f (x:xs)
| x∈f = True
| otherwise = x:f xs
的x∈f
沒有多大意義,但f x
一樣。如果f x
返回true,則將採取後衛變體。現在,這裏返回的True聽起來是正確的。它表示我們已經在列表中找到與謂詞相匹配的元素 - 並且看到了,可能是x
!
所以我們把注意力轉向最後一行。 otherwise
表示後衛f x
未返回True。因此,x
不滿足謂詞,所以我們必須搜索列表的其餘部分。
右邊x : f xs
是特有的。 :
表示我們將嘗試返回一個列表,但函數的返回類型是Bool
。如果我們嘗試這種方式,類型檢查器不會喜歡我們。此外,我們沒有理由再看x
,因爲我們只是確定它不符合謂詞。
你缺少的關鍵是我們需要遞歸在這一點上。我們需要以某種方式搜索列表的尾部xs
- 遞歸意味着調用尾部的exists
函數。
您的一般軌道是正確的,但再次詢問是否有不清楚的地方。一種訣竅可能是按照遞歸情況的類型:「我需要提供exists
才能返回Bool
值?」。
請注意`(x :: xs)`是一個錯字。它應該是`(x:xs)`。 – 2011-01-24 00:28:44