1

我正在寻找一种遍历列表的方法,抓取一个元素(我想按照给定的顺序),将它与另一个函数一起使用,然后返回该列表并继续操作而不会从列表中丢失该元素。

在示例中,我看到完成此操作的唯一方法是执行以下操作:

counter :: (Eq a1, Num a) => a1 -> [a1] -> a
counter a []            = 0
counter a [x]           = if a == x then 1 else 0
counter a (x:xs)        = if a == x then counter a xs + 1 else counter a xs


permut :: Eq a => [a] -> [a] -> Bool
permut [] []            = True
permut [x] []           = False

但是,当在 permut 中再次调用时,这会从列表 xs 中删除元素 x。我知道这也有助于结束递归调用/终止函数,但我需要在我的计数器函数中提供整个列表才能使其工作。我想简单地浏览一下列表并保持整个内容完好无损。这可能吗?

编辑:更新用例。我正在尝试检查一个列表是否是另一个列表的排列。我的思考过程是在每个列表中,如果它们是排列,则两个属性将保持:

  1. 它们将具有相同数量的总元素(稍后将实现此部分)

  2. 它们将具有相同数量的每个元素

现在我的计数器函数可以工作,但是当我递归地遍历 permut 函数时,我正在丢失元素。我不关心效率,我不介意再次计算相同的元素并比较它,如果该数字多次出现在列表中。

4

1 回答 1

3

您的模式匹配有点过于详尽,您需要检查所有元素的条件。它应该看起来像:

permut [] ys = null ys
permut xs ys = all condition xs
  where
    condition x = ....

额外建议:每当你发现自己在写作时是真的

if ..... then True else False

你写的太多了。

----- 附录:

所以你发现all,它确实遍历了列表(在我们的例子中是 xs),它会检查所有元素(在我们的例子中是 xs)的条件是否为真。例如:

all even [1,2,3]

是一种简短的说法:

even 1 && even 2 && even 3

因此,在您的 where 子句中,您可以condition访问原始的 xs 和 ys 列表,并为 xs 中的每个元素调用它。因此,您需要检查的只是参数 xcondition在 xs 和 ys 中出现的次数是否相同。为此,您已经有了counter,所以它将是一个单行。

于 2013-10-01T15:07:40.790 回答