haskell初始累加器'null'值

时间:2016-09-30 20:50:28

标签: haskell

我有一个看似简单的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)

1 个答案:

答案 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 xNothing,你就可以按照与列表上的模式匹配相同的方式对其进行模式匹配。

但是,在这种特殊情况下,我们可以提供更清洁的解决方案。请注意,该元素仅在您第一次 时调用compress'。我们可以通过向处理这种可能性的顶级compress函数添加一个案例来解决这个问题:

compress [] = []
compress (x:xs) = x : compress' xs x
  where ...

基本上,我们可以避免在我们的帮助器compress'函数中处理这种情况,如果我们在顶级函数中处理它,我们可以在传递的列表上匹配以确定要做什么。 / p>