我对haskell非常新,并且想知道是否有一个基本的例子,当它扔掉它时不会退出列表!
例如在这段代码中,我试图制作一个列表,用它来比较右边的数字,如果它更大,它会保留在列表中,否则我们将其删除,但它一直给我Prelude.head:空列表,因为它比较到最后我假设。我已经尝试过每一个我能想到的基础案例......任何人都可以帮助我吗?
maiores:: [Int]->[Int]
maiores [] = []
maiores (x:xs) | x > (head xs) = [x] ++ [maiores xs)
| otherwise = maiores xs
答案 0 :(得分:2)
如果您的函数传递了包含一个元素的列表,则它将与(x:xs)
匹配,xs
匹配[]
。然后你最终得到了head []
,从而得到了你的错误。为避免这种情况,请在两个现有案例之间添加一个基本案例maiores (x:[]) = ...
,并将其填入适当的位置。
另外:您可以将[x] ++ maiores xs
写为x : maiores xs
,这更自然,因为您解构了:
,然后立即使用修改后的值重新构建它,而不是间接使用{{ 1}}。
答案 1 :(得分:2)
切勿在代码中使用head
或tail
,除非您无法避免。这些是部分函数,当它们的输入为空时会崩溃。
相反,更喜欢模式匹配:而不是
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