如何保护这种情况

时间:2019-04-16 13:06:00

标签: haskell

我可以使用此功能尝试在列表列表中进行“注册”匹配:

processMatch :: String -> POSIXTime -> [[(String, POSIXTime)]] -> [[(String, POSIXTime)]]
processMatch host time hostList =
case hostList of
  []                 -> [[(host, time)]]
  ((host, t):x):tail -> ((host, t):(host, time):x):tail
  x:t                -> x:(processMatch host time t)

此问题是使用新值而不是条件重新声明主机。因此,无论主机匹配,最终我都将其添加到第一个匹配者的列表中。 我以为我需要改用警卫,但我想不通如何在警卫中解构清单,这有可能吗?

我可以在一些条件下以另一种方式进行操作,但我很好奇是否有可能像这样简单地执行操作。 谢谢!

1 个答案:

答案 0 :(得分:4)

我将从定义一个在hosttime结束的助手函数开始。除此之外,您可以命名对(host, time),因为它将在帮助程序定义的两个不同位置使用。

助手使用case表达式仅模式匹配内部列表的开头,而不是尝试匹配整个主机列表。

在与主机/时间对匹配的模式中,您需要使用单独的变量来捕获现有主机,然后然后将其与防护中的host进行比较。您只能在模式中直接匹配 literals

processMatch :: String -> POSIXTime -> [[(String, POSIXTime)]] -> [[(String, POSIXTime)]]
processmatch host time lst = go lst
    where newPair = (host, time)
          go [] = [[newPair]]
          go (head:tail) = case head of
                            (h,t):rest | h == host ->((h,t):newPair:rest):tail
                            otherwise -> head : go tail

顺便说一句,以前的输入错误使用了未定义的名称first,该名称来自答案的先前版本中的at-pattern。也许实际上值得使用,但是我将在这里提及而不是编辑主要答案:

first@(h,_):rest | h == host -> (first:newPair:rest):tail

这完成了两件事:1)避免在两边都重复(h,t); 2)它避免为匹配的时间起一个名字,只要您有first来指称配对本身,您就不会真正在意它。