2014-11-02 13 views
0

我有兩個功能這兩者的返回的列表:如何編寫map語句來比較haskell中兩個列表的每個元素?

enter earth = head $ do 
    lst <- earth 
    return $ map (\x -> if (x == 0) then 2 else x) lst 

helper earth = head $ do 
    lst <- tail (earth) 
    return lst 

其中大地是返回,例如[[1,2,3列表的列表]另一個函數,[2,3,4],[ 4,7,3]。在輔助函數中,我返回這個列表的第二個元素,即尾部的頭部。而在輸入功能中,只有頭部。現在我正在編寫另一個函數,我想將這兩個函數作爲參數傳遞給它。我這樣做:

see :: [Int] -> [Int] -> [Int] 
see enter helper = return $ map (\ x y -> if (x == 2) && (y == 0) then 2 else y) enter helper 

基本上,我試圖做的是檢查,如果返回的列表中輸入具有2和第二列表在此位置有一個零,然後更改爲0〜2否則讓第二個列表中的元素保持原樣。

我在這裏做錯了什麼?

編輯:

所以,有一個接地功能的返回這樣的:[[0,0,1],[1,0,1],[0,0,0]。輸入函數使用地球的頭部([0,0,1]),並使其像這樣:[2,2,1]。輔助函數接受並返回第二個元素(尾部的頭部)地球返回的列表清單([1,0,1])現在see函數將這些[2,2,1]和[1,0,1]作爲兩個參數,如果一個元素是2在第一個列表中,0在第二個列表中(即,從這個例子中,這兩個列表中的第二個元素,那麼0應該在第二個列表中變成2,並且應該返回應該是這樣的:[1, 2,1]

+1

使用一些'zip'功能? – 2014-11-02 21:34:48

回答

1

它看起來像你想是這樣的:

 xs = [ ...,  1,  2,  0,  1, ... ] 
     ys = [ ...,  3,  0,  4,  0, ... ] 
zip xs ys = [ ..., (1,3), (2,0), (0,4), (1,0), ... ] 
    result = [ ...,  3,  2,  4,  0, ... ] 

result是列表ys與2S替換那裏是零在列表xs中有2個。

所以你幾乎可以直接表達這種邏輯列表理解:

result = [ r | (x,y) <- zip xs ys, let r = if y == 0 && x == 2 then 2 else y ] 
+0

所以,現在我正在寫這樣的東西:see = [r | (x,y)< - zip輸入助手,讓r = if y == 0 && x == 2 then 2 else y]但是我得到一個類型錯誤。 – 2014-11-03 00:10:44

+0

'enter'和'helper'是函數,而不是列表。如果'as'是一個列表,那麼'enter as'也是一個列表,所以你希望用'help as'替換'xs',用'helper bs'替換''as'和'bs ' – ErikR 2014-11-03 00:27:03

+0

我解決了這個問題。你能告訴我,如果我可以在列表理解中寫一些嵌套的if語句嗎?像返回結果的列表一樣,我想對該列表的每個元素進行一些計算。如果在這個列表理解的範圍內,這可能會嵌套嗎? – 2014-11-03 01:30:38

2

zipWith是,你要尋找的功能。map只能一個列表上的時間,所以你對它的使用將導致一個類型錯誤。如果你只是在zipWith取代map最後一行,它應該工作。此外,你應該刪除return。在列表的上下文中,return僅將某些內容放入單例列表中:return x = [x]。請注意0​​是一個函數,與C語言中的return沒有真正關聯。我還建議此時不要使用do表示法列表。

此外,最後一個函數不使用其他兩個函數,即使它使用這些名稱。我不確定這是不是你想要或不是。它相當於see的定義,其中您使用名稱xy而不是enterhelper

這裏是zipWith行爲的一個例子:

λ> zipWith (*) [2, 3, 4] [10, 100, 1000] 
[20,300,4000] 
+0

我不明白你的意思,我的最後一個功能不需要輸入和幫助功能。它只從這些函數中獲取兩個列表,並在其上執行計算。 :O – 2014-11-03 00:17:37

+0

@EricaMaine噢,我只是說這些參數不需要與其他函數具有相同的名稱,但它會以任何方式工作。另一方面,我的意思不是在'see'函數中使用'map',而是想使用'zipWith'。 'zipWith'具有您描述的以您想要的方式在兩個列表中應用兩個參數函數的行爲(請參閱文檔鏈接luqui添加到我的答案以供參考)。 – 2014-11-03 01:44:03

+0

@EricaMaine我添加了一個演示'zipWith'如何工作。此外,它看起來像有一個術語問題:「地球」是一個列表,而不是一個函數(不是我今天想要說的,哈哈)。 – 2014-11-03 01:45:39

1

map只有走過去1個列表,但你試圖在同一時間走過去2列出,並計算出一些東西。

所以你需要一個函數,它接受一個函數有兩個參數,2所列出並返回一個列表與同類型的函數的結果:(a -> b -> c) -> [a] -> [b] -> [c]

而且hoogle發現具有這種特性的功能:zipWith

所以你寫一個輔助功能,你想要做什麼:

helper 0 2 = 2 
helper _ y = y 

現在你寫的看功能,把輔助函數在where子句中(你可能並不需要使得f結後):

see a b = zipWith helper a b 
    where helper 2 0 = 2 
      helper _ y = y 

我不知道爲什麼你使用do但在這裏,這是沒有必要的。