[英]How to write a map statement to compare each elements of two lists in 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
這里earth是另一個函數,它返回列表的列表,例如[[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
我基本上想做的是檢查enter返回的列表在該位置是否具有2,第二個列表在該位置具有零,然后將其更改為0到2,否則讓第二個列表中的元素保持原樣。
我在這里做錯了什么?
編輯:
因此,有一個地球函數返回如下:[[0,0,1],[1,0,1],[0,0,0]]。 enter函數獲取地球的頭部(即[0,0,1]並使其如下:[2,2,1]。helper函數獲取並返回地球的第二個元素(尾部的頭部)地球返回的列表的列表(即[1,0,1])現在,see函數將這些[2,2,1]和[1,0,1]用作兩個參數,並且如果一個元素是在第一個列表中為2,在第二個列表中為0(即,在本示例中,兩個列表中的第二個元素,那么0應該在第二個列表中變為2,應返回的內容應類似於:[1, 2,1]
zipWith
是您要查找的功能。 map
只能在一個列表上使用,因此使用它會導致類型錯誤。 如果僅在最后一行用zipWith
替換map
,它應該可以工作。 另外,您應該刪除return
。 在列表的上下文中, return
僅將某些內容放入單例列表中: return x = [x]
。 請注意, return
是一個函數,與C影響語言中的return
並沒有真正的關系。 我也建議此時不要對列表使用do
表示法。
同樣,最后一個函數即使使用了這些名稱,也沒有使用其他兩個函數。 我不確定這是否是您想要的。 它等效於see
的定義,其中您使用了名稱x
和y
而不是enter
和helper
。
這是zipWith
行為的zipWith
:
λ> zipWith (*) [2, 3, 4] [10, 100, 1000]
[20,300,4000]
看起來您想要這樣的東西:
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 ]
map
僅遍歷1個列表,但是您嘗試同時遍歷2個列表,並進行計算。
因此,您需要一個函數,該函數需要一個具有2個參數,2個列表的函數,並返回具有與函數結果相同類型的列表: (a -> b -> c) -> [a] -> [b] -> [c]
hoogle找到具有此屬性的函數: zipWith
因此,您編寫了一個輔助函數,該函數可以執行您想要的操作:
helper 0 2 = 2
helper _ y = y
現在,您編寫了see函數並將helper函數放在where子句中(您以后可能不需要該函數):
see a b = zipWith helper a b
where helper 2 0 = 2
helper _ y = y
我不知道您為什么使用do
但這在這里是不必要的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.