简体   繁体   English

如何编写一个map语句来比较haskell中两个列表的每个元素?

[英]How to write a map statement to compare each elements of two lists in haskell?

I have two functions both of which return a list: 我有两个函数都返回一个列表:

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

where earth is another function that returns a list of lists like [[1,2,3],[2,3,4],[4,7,3]]. 这里earth是另一个函数,它返回列表的列表,例如[[1,2,3],[2,3,4],[4,7,3]]。 In the helper function, I am returning the second element of this list of lists, ie, the head of the tail. 在辅助函数中,我将返回列表的第二个元素,即尾巴的头部。 And in the enter function, only the head. 在回车功能中,只有头部。 Now I am writing another function and I want to pass these two functions as arguments to it. 现在,我正在编写另一个函数,我想将这两个函数作为参数传递给它。 I'm doing this: 我正在这样做:

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

I'm basically trying to do is to check if the list returned by enter has a 2 and the second list has a zero at that location, then change that 0 to 2 otherwise let the element in the second list be as it is. 我基本上想做的是检查enter返回的列表在该位置是否具有2,第二个列表在该位置具有零,然后将其更改为0到2,否则让第二个列表中的元素保持原样。

What am I doing wrong here? 我在这里做错了什么?

EDIT: 编辑:

So, there is an earth function returning like this: [[0,0,1],[1,0,1],[0,0,0]]. 因此,有一个地球函数返回如下:[[0,0,1],[1,0,1],[0,0,0]]。 The enter function, takes the head of earth(which is [0,0,1] and makes it like this: [2,2,1]. The helper function takes and returns the second element (the head of the tail) of the list of lists returned by earth (which is [1,0,1]). Now the see function, takes these [2,2,1] and [1,0,1] as two arguments, and if an element is 2 in the first list and 0 in the second list (ie, from this example, the second element in both lists, then that 0 should become 2 in the second list, and what should be returned should be something like this: [1,2,1] 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 is the function that you're looking for. zipWith是您要查找的功能。 map only works on one list at a time, so your usage of it will result in a type error. map只能在一个列表上使用,因此使用它会导致类型错误。 If you just replace map with zipWith in that last line, it should work. 如果仅在最后一行用zipWith替换map ,它应该可以工作。 Also, you should remove the return . 另外,您应该删除return In the context of a list, return only puts something into a singleton list: return x = [x] . 在列表的上下文中, return仅将某些内容放入单例列表中: return x = [x] Note that return is a function and is not really related to the return in C-influenced languages. 请注意, return是一个函数,与C影响语言中的return并没有真正的关系。 I would also suggest not using do notation for lists at this point. 我也建议此时不要对列表使用do表示法。

Also, the last function isn't using the other two functions, even though it uses those names. 同样,最后一个函数即使使用了这些名称,也没有使用其他两个函数。 I'm not sure if this is what you want or not though. 我不确定这是否是您想要的。 It is equivalent to a definition of see where you used the names x and y instead of enter and helper . 它等效于see的定义,其中您使用了名称xy而不是enterhelper

Here's an example of the behavior of zipWith : 这是zipWith行为的zipWith

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

It looks like you want something like this: 看起来您想要这样的东西:

       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 is the list ys with the zeros replaced with 2s where there is a 2 in the list xs . result是列表ys的零被2s取代,其中列表xs中有2。

So you can express this logic pretty much directly as a list comprehension: 因此,您可以将其直接表达为列表理解:

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

map only walks over 1 list, but you try to walk over 2 lists at the same time, and calculate something. map仅遍历1个列表,但是您尝试同时遍历2个列表,并进行计算。

So you need a function which takes a function with 2 parameters, 2 lists and returns a list with the same type of the result of the function: (a -> b -> c) -> [a] -> [b] -> [c] 因此,您需要一个函数,该函数需要一个具有2个参数,2个列表的函数,并返回具有与函数结果相同类型的列表: (a -> b -> c) -> [a] -> [b] -> [c]

And hoogle finds a function which has this property: zipWith hoogle找到具有此属性的函数: zipWith

So you write a helper function which does what you want: 因此,您编写了一个辅助函数,该函数可以执行您想要的操作:

helper 0 2 = 2
helper _ y = y

now you write the see function and put the helper function in a where clause (you probably don't need that function later): 现在,您编写了see函数并将helper函数放在where子句中(您以后可能不需要该函数):

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

I don't know why you use do but this is not necessary here. 我不知道您为什么使用do但这在这里是不必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM