简体   繁体   English

Haskell递归列表

[英]Haskell recursion in lists

I have code like this: 我有这样的代码:

appd (a:e) ((c,b):bs) | a == c && bs /= [] = b:appd(a:e) bs
                      | a /= c && bs /= [] = appd (a:e) bs
                      | a /= c && bs == [] = appd e ((c,b):bs)
                      | otherwise          = b:appd e ((c,b):bs)

It loops throught two lists like [1,2,3] and [(1,2),(6,5),(3,5)] and takes first element of first list and compares it to first element of each tuple in other list, if they are equal then save second element of this tuple. 它循环遍历两个列表,例如[1,2,3][(1,2),(6,5),(3,5)]并获取第一个列表的第一个元素,并将其与每个元组的第一个元素进行比较其他列表,如果它们相等,则保存此元组的第二个元素。 It works fine, but comparison does not work if I take second element of first list, in this case 2 . 它工作正常,但如果我采用第一个列表的第二个元素(在这种情况下为2 ,则比较不起作用。

For example if I have lists like [1,2,3] and [(1,2),(6,5),(3,5)] , then function takes 1 from first list and compares to 1 , then to 6 , then to 3 , that works but it does not take second element of first list - 2 and does not do the comparison again. 例如,如果我有[1,2,3][(1,2),(6,5),(3,5)]列表,则函数从第一个列表中获取1并与1比较,然后与6 ,然后到3 ,这是可行的,但它不占用第一个列表的第二个元素2 ,并且不再进行比较。 Whats wrong? 怎么了?

First of all, let me note that you should have included the error message you were getting. 首先,请允许我注意您应该包括收到的错误消息。 You should also have shown us some sample output and sample input. 您还应该向我们展示了一些示例输出和示例输入。


Anyway: your current appd doesn't handle empty lists, so you need to start by adding cases for that: 无论如何:您当前的appd不会处理空列表,因此您需要为此添加案例:

appd _     []          = []
appd []    bs          = snd <$> bs  -- you can decide to use [] instead
appd (a:e) ((c,b):bs)
  | a == c && bs /= [] = b:appd(a:e) bs
  | a /= c && bs /= [] = appd (a:e) bs
  | a /= c && bs == [] = appd e ((c,b):bs)
  | otherwise          = b:appd e ((c,b):bs)

now your function works on the input you've provided, but I'm not sure it returns the results you desire: 现在,您的函数可以在您提供的输入上使用,但是我不确定它是否返回您想要的结果:

*Main> appd [1,2,3] [(1,2),(6,5),(3,5)]
[2,5,5]

Furthermore , I've cleaned up your code a little bit and annotated your function with an explicit type signature: 此外 ,我还对您的代码进行了一些整理,并使用显式类型签名为您的函数添加了注释:

appd :: (Eq a, Eq b) => [a] -> [(a,b)] -> [b]
appd []         bs      = snd <$> bs
appd _          []      = []
appd as@(a:ass) bs@((c,b):bss)
  | a == c && bss /= [] = b : appd as  bss
  | a /= c && bss /= [] =     appd as  bss
  | a /= c && bss == [] =     appd ass bs
  | otherwise           = b : appd ass bs

Also , you can use a much simpler, non-recursive implementation to get the same results as above: 另外 ,您可以使用更简单的非递归实现来获得与上述相同的结果:

appd :: (Eq a, Eq b) => [a] -> [(a,b)] -> [b]
appd as bs = snd <$> filter (\(a,_) -> a `elem` as) bs

or if you like point free (aka tacit ): 或者,如果您喜欢无积分 (又称默认 ):

appd :: (Eq a, Eq b) => [a] -> [(a,b)] -> [b]
appd as = (snd <$>) . filter ((`elem` as) . fst)

Note: <$> is an alias for fmap , which in turn behaves exactly like map when used on lists. 注意: <$>fmap的别名,当在列表map使用时, fmap行为与map完全相同。

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

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