基本情况下没有走出名单?

时间:2017-03-24 04:55:22

标签: haskell

我对haskell非常新,并且想知道是否有一个基本的例子,当它扔掉它时不会退出列表!

例如在这段代码中,我试图制作一个列表,用它来比较右边的数字,如果它更大,它会保留在列表中,否则我们将其删除,但它一直给我Prelude.head:空列表,因为它比较到最后我假设。我已经尝试过每一个我能想到的基础案例......任何人都可以帮助我吗?

maiores:: [Int]->[Int]
maiores [] = []
maiores (x:xs) | x > (head xs) = [x] ++ [maiores xs)
               | otherwise = maiores xs

3 个答案:

答案 0 :(得分:2)

如果您的函数传递了包含一个元素的列表,则它将与(x:xs)匹配,xs匹配[]。然后你最终得到了head [],从而得到了你的错误。为避免这种情况,请在两个现有案例之间添加一个基本案例maiores (x:[]) = ...,并将其填入适当的位置。

另外:您可以将[x] ++ maiores xs写为x : maiores xs,这更自然,因为您解构了:,然后立即使用修改后的值重新构建它,而不是间接使用{{ 1}}。

答案 1 :(得分:2)

切勿在代码中使用headtail,除非您无法避免。这些是部分函数,​​当它们的输入为空时会崩溃。

相反,更喜欢模式匹配:而不是

foo [] = 4
foo (x:xs) = x + head xs + foo (tail xs)

foo [] = 4
foo (x1:x2:xs) = x1 + x2 + foo xs

现在,如果我们使用-Wall启用警告,GHC会建议匹配并非详尽无遗:我们忘记处理[_]案例。所以,我们可以相应地修改程序

foo [] = 4
foo [x] = x
foo (x1:x2:xs) = x1 + x2 + foo xs

答案 2 :(得分:1)

只需使模式匹配更具体。因为(:)是右关联的:

maiores:: [Int]->[Int]
maiores [] = []
maiores (x : y : xs) | x > y = [x] ++ maiores (y:xs)
maiores (_ : xs) = maiores xs