我有一个看似简单的Haskell问题,而且由于我的知识有限,我不确定要搜索哪些术语来解决它。
我试图解决99个Haskell问题中的问题8(从列表中删除连续的重复项),这就是我想出的:
compress :: (Eq a) => [a] -> [a]
compress list = compress' list ???
where
compress' [] _ = []
compress' (x:xs) last
| x == last = compress xs last
| otherwise = x : compress xs x
'???'只是一个占位符,这是我不确定该怎么做的地方。我认为片段的工作方式应该足够清楚,“last”是一种累加器,用于检查元素是否与之前的元素重复。 现在,在这种情况下,我可以给出“最后”的初始值吗? (在我想的大多数OO语言中类似于'null')。
编辑:Tikhon的答案有效,但是我刚刚意识到我在原帖中犯了一个错误,压缩'应该递归调用自己而不是压缩。因此,现在我的问题的“琐碎”解决方案是:
compress :: (Eq a) => [a] -> [a]
compress list = compress' list Nothing
where
compress' [] _ = []
compress' (x:xs) Nothing = x : compress' xs (Just x)
compress' (x:xs) (Just last)
| x == last = compress' xs (Just last)
| otherwise = x : compress' xs (Just x)
答案 0 :(得分:9)
所以你的问题有两个答案。更直接的答案是你可以使用Maybe
来制作可以为空的东西,类型系统会确保你每次使用时检查某些东西是否为Nothing
:
compress list = compress' list Nothing
where compress' [] _ = []
compress' (x:xs) Nothing = x : compress xs (Just x)
compress' (x:xs) (Just last)
| x == last = compress xs last
| otherwise = x : compress xs (Just x)
故事的寓意是,如果你有一个可能缺失的元素(即在其他语言中可能是null
),你将它包装在Maybe
中。然后你要么拥有Just x
或Nothing
,你就可以按照与列表上的模式匹配相同的方式对其进行模式匹配。
但是,在这种特殊情况下,我们可以提供更清洁的解决方案。请注意,该元素仅在您第一次 时调用compress'
。我们可以通过向处理这种可能性的顶级compress
函数添加一个案例来解决这个问题:
compress [] = []
compress (x:xs) = x : compress' xs x
where ...
基本上,我们可以避免在我们的帮助器compress'
函数中处理这种情况,如果我们在顶级函数中处理它,我们可以在传递的列表上匹配以确定要做什么。 / p>