list - 为什么这个删除 Haskell 中的重复函数有两个参数而不是一个?

帮助我理解为什么函数 removeDuplicates 只有一个参数,但它下面的函数 rdHelper 有两个?它有效,并且在列表中尝试没有错误。

removeDuplicates :: Eq a => [a] -> [a] 
removeDuplicates = rdHelper []     
    where rdHelper seen [] = seen  
          rdHelper seen (x:xs)
              | x `elem` seen = rdHelper seen xs 
              | otherwise = rdHelper (seen ++ [x]) xs

也许它与状态变量有关?但我不确定它是什么

最佳答案

为了删除重复项,您需要以某种方式存储您已经看到的值。这就是变量被称为seen 的原因。最初在递归中,您没有看到任何元素,因此 seen 为空。

但是,每次您发出 一个值时,都会将其添加到累加器seen。假设您调用 removeDuplicates [1,2,3,1,4,2]。然后它将被评估为:

removeDuplicates [1,2,3,1,4,2]
    rdHelper [] [1,2,3,1,4,2]
        (1 : rdHelper [1] [2,3,1,4,2])

所以现在 rdHelper 将被调用,我们知道 1 已经发出,所以我们应该将其过滤掉。接下来我们执行:

removeDuplicates [1,2,3,1,4,2]
    rdHelper [] [1,2,3,1,4,2]
        (1 : rdHelper [1] [2,3,1,4,2])
            (1 : 2 : rdHelper [1,2] [3,1,4,2])
                (1 : 2 : 3 : rdHelper [1,2,3] [1,4,2])

所以现在我们遇到这样一种情况,其中 1 位于第二个列表的头部,但因为它也是 seenelem,我们将忽略该元素。

您的代码中存在错误,因为 rdHelper 从不发出任何内容。还要注意,您可以通过添加到头部来提高性能(添加到头部不会改变程序的语义,但会使其运行得更快):

removeDuplicates :: Eq a => [a] -> [a] 
removeDuplicates = rdHelper []     
    where rdHelper _ [] = []  
          rdHelper seen (x:xs)
              | x `elem` seen = rdHelper seen xs 
              | otherwise = <b>x : </b>rdHelper <b>(x:seen)</b> xs
--                          ^emit element  ^add to head

https://stackoverflow.com/questions/42489878/

相关文章:

oracle - Windows 的 ins-32025 oracle 11g 错误

html - 将鼠标悬停在文本上时显示图像

date - 如何将天数添加到 Cypher 中的日期属性?

indexing - solr 的 WSO2 API 管理器问题

c# - 无法将类型为 'System.DateTime' 的对象转换为类型 'System.Str

spring-mvc - 如何在应用程序中使用 "RestController"和 "Control

spring-boot - 将所有 Zuul 代理请求动态重新路由到单个 URL

c# - 在 NSubstitute 中使用 IEnumerable 设置参数匹配器

xml - “||” (OR) 在XML中怎么写?

php - 所有链接都重定向到 localhost/dashboard/with codeignit