我是Haskell的新手,我正在尝试以下代码从列表中删除重复项。但它似乎不起作用。
compress [] = []
compress (x:xs) = x : (compress $ dropWhile (== x) xs)
我尝试了一些搜索,所有建议都使用了foldr / map.head。是否有使用基本结构的实现方式?
我是Haskell的新手,我正在尝试以下代码从列表中删除重复项。但它似乎不起作用。
compress [] = []
compress (x:xs) = x : (compress $ dropWhile (== x) xs)
我尝试了一些搜索,所有建议都使用了foldr / map.head。是否有使用基本结构的实现方式?
我认为你在代码中提到的问题是,你当前的实现只能消除相邻的重复项。正如在评论中发布的一样,内置函数nub将消除每个重复项,即使它们不是相邻的,并仅保留任何元素的第一次出现。但既然你问了如何使用基本结构实现这样的函数,那么这个怎么样?
myNub :: (Eq a) => [a] -> [a]
myNub (x:xs) = x : myNub (filter (/= x) xs)
myNub [] = []
我在这里向您介绍的唯一新功能是filter,它可以根据谓词(在本例中,为了摆脱与当前元素匹配的列表其余元素)过滤列表。
希望这有所帮助。
首先,在问题中不要简单地陈述“不起作用”。这会让读者检查它是编译时错误、运行时错误还是错误的输出结果。
在这种情况下,我猜测它是错误的输出结果,就像这样:
> compress [1,1,2,2,3,3,1]
[1,2,3,1]
foldr和map是非常基本的FP构造。然而,它们非常通用,我很长一段时间都觉得它们有点令人费解。Tony Morris的演讲“向自己解释列表折叠”对我帮助很大。
在您的情况下,可以使用具有排除重复项谓词的现有列表函数,例如filter :: (a -> Bool) -> [a] -> [a]代替dropWhile。
dropWhile
函数不正确。dropWhile
会删除列表中每个元素,直到遇到一个等于x
的元素;您需要删除所有像那样的元素。 - Tikhon JelvisData.List
模块中有一个内置的名为nub
的函数可以实现此功能。 - SibidropWhile (==1) [1,1,1,2,3,1,4,5,6] ==> [2,3,1,4,5,6]
。 - chi