2011-02-19 31 views
3

對於我在哈斯克爾的第一次演講,我們給出了一系列問題。其中之一是在列表中存在n個數字時返回True,否則返回False。我設法得到了我認爲在那裏的一半,但是得到了不同的編譯錯誤,並且非常沮喪,因爲我甚至可以理解它們的意思。Haskell:寫一個函數來複制``ellem'

到目前爲止,我已經做了以下

// No problem with this function 
matches :: Int -> [Int] -> [Int] // This function is to return the matches 
matches x y = [a | a <-y, a==x]  // ie. main> 1 [1,3,5,7,1,4] outputs [1,1] 

// Here am stuck 
myelem :: Int -> [Int] -> Bool 
myelem x [] = False 
myelem x (y:ys) 
| x == y = y : x myelem ys  // Am not sure about recursion as 
            // we have not yet covered 

顯然,這是一類,所以請不要發佈答案。但也許有一些例子可以幫助我推理Haskell的運作以及如何解決這個問題。任何指針都將被大量讚賞。


SOLUTION

matches :: Int -> [Int] -> [Int] 
matches x y = [a | a <-y, a==x] 

myelem :: Int -> [Int] -> Bool 
myelem x [] = False 
myelem x (y:ys) 
| x == y = True 
| otherwise = myelem x (ys) 

乾杯傢伙

+0

@pelotom,@Jeremiah Willcock,@ 9000:非常感謝這麼多人,我只是覺得把我的推理從強制性轉變爲陳述性是非常具有挑戰性的。只是爲了澄清;當`myelem x(ys)`被執行時,它實際上是否從列表中刪除了元素直到爲空,還是僅僅評估列表上剩餘的元素,直到沒有剩下的元素爲止? – Carlos 2011-02-19 03:13:17

回答

2

的問題是在你的最後一個等式:

myelem x (y:ys) 
| x == y = y : x myelem ys 

有兩個問題在這裏:

  1. 如果你想使用myelem作爲中綴運算符,你必須圍繞着它的反引號,像這樣:

    x `myelem` ys 
    
  2. 鑑於這就是你的意思,你的方程的右邊沒有鍵入檢查;列表構造函數(:)要求其第二個參數是列表,而不是Bool。此外,(:)構建一個列表,而myelem應該返回一個Bool

想想你想做什麼。如果x == y,您只想返回True,對不對?並且otherwise,您要返回檢查列表的其餘部分(ys)的結果。希望有所幫助。

1

你實際上是非常接近正確答案。但我看到兩個主要問題。一種是在最後一行代碼上調用myelem需要在其周圍有反引號(x `myelem` ys)或者沒有反引號的前綴調用(myelem x ys)。另外,您不希望將y添加到遞歸調用的結果中。實際上,您不需要第二種模式的條件:只需考慮使用簡單的布爾運算和遞歸調用您應該返回的內容即可返回myelem x (y:ys)

1

您嘗試連接最後一行中的IntBool;再想一想。

你永遠不會從myelem返回True;有時候是合適的。

一旦這些問題得到解決,代碼就可以工作。

0

請注意,您還可以根據matches定義您的myelem函數。

  • 如果項目不在列表中,將返回什麼?
  • 如果項目在列表中一次會返回什麼?兩次?多次?
  • 你關心第二種情況下的整個回報價值嗎? (提示:無)
1

您還可以使用以下功能的一些組合寫你的函數(有使用下面的功能做的至少兩種方式):

filter :: (a -> Bool) -> [a] -> [a] 

從刪除元素列表,除非它們滿足一些準則集列表

null :: [a] -> Bool 

回報是否爲空或不

not :: Bool -> Bool 

是邏輯否定

or :: [Bool] -> Bool 

返回true布爾列表包含一個或多個真實值。

顯然,你已經解決了你的問題,但它可能會幫助你探索其他方法來做同樣的事情。