【问题标题】:Adding contents of two different size lists haskell添加两个不同大小列表的内容haskell
【发布时间】:2017-10-17 04:09:51
【问题描述】:

我正在尝试实现一个将两个列表的内容相加的函数。这是我的代码:

sum'' :: Num a => [a] -> [a] -> [a]
sum'' [] [] = []
sum'' (x:xs) (y:ys) = (x + y) : sum'' xs ys

如果我输入:

sum'' [1,2,3] [4,5,6]

我得到[5,7,9],这就是我想要的。我遇到的问题是不同的列表大小。如果我输入:

sum'' [] [1,2,3]

我希望它返回 []。或者

sum'' [1,2] [4,5,6]

我希望它返回[5,7]。我收到此错误,不知道为什么:Non-exhaustive patterns in function sum''

任何帮助将不胜感激。

【问题讨论】:

  • 使用 -Wall 标志打开警告会使 GHC 在编译时警告错过的案例。推荐。

标签: list haskell functional-programming pattern-matching


【解决方案1】:

在定义sum'' 时,您已经定义了两个空列表和两个非空列表的含义,但是您还没有定义两个列表的含义,其中只有一个是空的。这就是编译器通过该错误消息告诉您的内容。

只要左列表为空而右列表不为空,只需添加 sum'' 的定义即可,反之亦然:

sum'' (x:xs) [] = ...
sum'' [] (y:ys) = ...

【讨论】:

  • 而且,作为一个可爱的技巧,如果您的 [] [](x:xs) [][] (y:ys)] 子句都返回相同的内容,您可以考虑使用 sum'' (x:xs) (y:ys) = ...; sum _ _ = ...
  • @Fyodor Soikin 感谢您的帮助,但我仍然对问题的第二部分如何做感到困惑。 sum'' [1,2] [4,5,6] 仅返回 [5,7] 并将 6 放入第二个列表中
  • @DanielWagner 你会不会碰巧知道问题的第二部分。 sum'' [1,2] [4,5,6] 仅返回 [5,7] 并将 6 放在第二个列表中。不是从字面上做到这一点,但任何指导表示赞赏。我试过这样做:sum _ _ = ... if your [] [], (x:xs) [], and [] (y:ys)],但它只给了我一个错误。所有子句都返回相同的内容。
  • @legoniko 如果其中一个列表较短,则递归最终将达到一个为空而另一个不是空的情况。你需要定义这两种情况下的结果是什么,才能得到你想要的。
  • @molbdnilo 谢谢!我犯了一个语法错误,这就是它不起作用的原因。很高兴知道代码背后的原因。再次感谢您!
【解决方案2】:

在 Haskell 中,实际上您需要的是 ZipList 类型,您可以使用它来简单地执行以下操作;

import Control.Applicative

addLists :: Num a => [a] -> [a] -> [a]
addLists xs ys = getZipList $ (+) <$> ZipList xs <*> ZipList ys

*Main> addLists [3] [1,2,3]
[4]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 2013-11-10
    相关资源
    最近更新 更多