Haskell -查找元素



我是haskell新手。我的练习是编写一个谓词来检查一个元素是否存在于列表中。但我必须解决使用线性递归过程没有模式匹配。

isPresentRecNonPM :: Int -> [Int] -> Bool
isPresentRecNonPM y (x:xs)
| null xs = False
| y == x = True
| otherwise = isPresentRecNonPM y xs
那是我的代码,但是我找不到我的错误。你能帮我吗?我的代码有什么问题?

您过早地返回了False,因为null xs检查非空列表参数的尾部是否为空。

isPresentRecNonPM :: Int -> [Int] -> Bool
isPresentRecNonPM _ xs | null xs = False
isPresentRecNonPM y (x:xs)
| y == x = True
| otherwise = isPresentRecNonPM y xs

既然你应该避免模式匹配,我怀疑你也不应该使用(x:xs),并在确认参数不为空后显式地使用headtail

isPresentRecNonPM :: Int -> [Int] -> Bool
isPresentRecNonPM y xs
| null xs = False
| head xs == y = True
| otherwise = isPresentRecNonPM y (tail xs)

(如果他们真的不使用模式匹配,您还需要避免不可辩驳的模式yxs,并以无点样式定义函数。)

正在使用模式匹配。实际上,您使用(x:xs),这是列表类型的模式。您应该使用xs来匹配整个列表,因此:

isPresentRecNonPM :: Int -> [Int] -> Bool
isPresentRecNonPM yxs
| nullxs= False
| y == headxs= True
| otherwise = isPresentRecNonPM y (tailxs)

你可以进一步简化它:

isPresentRecNonPM :: Int -> [Int] -> Bool
isPresentRecNonPM y = go
where go xs
|nullxs = False
| y ==headxs = True
| otherwise = go (tailxs)

我们可以把它写成:

isPresentRecNonPM :: Int -> [Int] -> Bool
isPresentRecNonPM y = go
where go xs = not (null xs) && (y == head xs || go (tail xs))

话虽这么说,但由于headtail是非全函数,因此通常使用模式匹配会更好。

由于错误地使用了模式匹配,您没有处理空列表。

我很确定你根本不应该做任何单独的案例分析,而是考虑谓词为真的条件,并编写单个逻辑表达式。

当且仅当

此谓词为真
  • 列表不为空,
  • 您要查找的是第一个元素,它位于列表的尾部。
  • 在代码中,

isPresentRecNonPM  y xs = not (null xs) 
&& (y == head xs || isPresentRecNonPM  y (tail xs))

相关内容

  • 没有找到相关文章

最新更新