haskell 检查元组以查看是否为列表中同一元素分配了不同值

falq053o  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(138)

刚到 haskell ,想解决问题。
我正在创建一个函数conflicts,其签名为conflicts :: Tuples -> Bool,其中元组为type Tuples = [(Char,Int)]。该函数的目的是检查同一字符是否被赋予了不同的整数,如果相同的字符被赋予了不同的冲突值,则返回false-例如,conflicts [('d', 2), ('f', 1)]将返回True,因为f和d是被赋予了不同值的独立字符。然而,conflicts [('f', 2), ('f', 1)]会传回False,因为'f'已指派给2和1。此外,conflicts [('f', 2), ('f', 2)]会传回True,因为f在两种情况下都指派了值2-因此值之间没有恩怨。conflicts [('f', 2), ('f', 2), ('c', 6), ('d', 4)]会传回False,依此类推。
到目前为止,我已经尝试了下面的方法,但它并不总是产生预期的输出。我认为它只检查是否至少有一对列表具有相同的字符和整数-如果是这种情况,它返回True。然而,这不是我要寻找的输出;我还想检查字符相同但整数不同的条件(因此应返回False)。

conflicts:: Tuples -> Bool; conflicts = \case { [] -> True; x:xs -> any (== x) xs}

如果有人能帮我解决这个问题,我将不胜感激。谢谢。

but5z9lq

but5z9lq1#

您的解决方案检查列表的尾部xs是否包含与头部x相等的元组(即相同的字符和整数)。
你可以修改它,使用lookup :: Eq a => a -> [(a,b)] -> Maybe b来查找具有相同字符的元组。同样,即使第一个元素没有冲突,你也必须继续在尾部查找冲突,并递归调用你的函数(想象一个列表[('a',0),('b',1),('b',2)])。
最后,解决方案如下所示:

{-# LANGUAGE LambdaCase #-}
type Tuples = [(Char, Int)]

conflicts :: Tuples -> Bool
conflicts = \case 
  [] -> False                          -- empty list has no conflicts
  (x,c) : tuples -> case lookup x tuples of
    Nothing -> conflicts tuples        -- no `x` in the rest of list, continue checks
    Just d
      | c /= d -> True                 -- found a conflict
      | otherwise -> conflicts tuples  -- the same assignment, continue checks

这里我使用模式匹配来提取字符x及其赋值c

相关问题