比较haskell中的元组列表

时间:2015-10-20 13:02:47

标签: list haskell functional-programming tuples

好吧,我对Haskell非常陌生,就像我今天早上开始学习一样,并且已经承担了2个元组列表[(“s”,1)..]并且如果他们有相同的话则返回true否则返回false。 到目前为止,我正在考虑从列表1中获取第一个元素并将其与列表2中的所有元素进行比较,并对所有元素执行此操作,然后返回true或false。我不知道如何跟踪所有布尔值,如果有错误则很容易。

|head list1 =/ elementList2 = False

但我只是混淆了我的自我,到目前为止,我已经定义了List

listCheck :: List->List -> Bool
listCheck (h1:t1) (h1:t1)
    | h1 == [] = True
    | fst (head h1) /= fst (head h2) = False
    | snd (head h1) /= snd (head h2) = False
    | otherwise = listCheck (t1) (t2)

有什么建议吗? 列表可以是任何顺序,因此[(“a”,1),(“b”,1)]和[(“b”,1),(“a”,1)]相等。列表的顺序无法更改。

4 个答案:

答案 0 :(得分:2)

我认为采用列表的头部并使用它创建一个相等的函数是合理的。使用List library中的anyall来与尾部进行比较。

由于这是一次大学练习,我猜你不想给你答案; - )

答案 1 :(得分:0)

listCheck l1 l2 = sort l1 == sort l2
如果列表元素是完全有序的,那么

将正常工作,它们通常是字符串,数字等(以及这些元素的自然元组)。

如果你的元素没有订购,那么事情会变得更加困难,但我认为你不会经常遇到这种情况。

答案 2 :(得分:0)

我总是建议新手解决这个问题的方法是:

  1. 寻找使用标准库函数解决问题的方法。
  2. 当你成功完成时,请编写你自己使用的每个库函数的版本。
  3. 在这种情况下,您对所思考内容的描述可以简化为#1式解决方案。我们引用它:

      

    到目前为止,我正在考虑从列表1中获取第一个元素并将其与列表2中的所有元素进行比较,然后对所有元素执行此操作,然后返回true或false。

    在这里,与其考虑仅使用第一个元素进行操作,图片对 all 元素执行相同的操作,作为解决方案的一个步骤。这是一个捕获这种模式的标准函数:

    -- The `map` function applies the function given as the first argument
    -- to all of the elements of the second argument.  The result is a list
    -- of all the individual results.
    --
    -- Example:
    --
    -- >>> map (+10) [1, 2, 3, 4]
    -- [11, 12, 13, 14]
    map :: (a -> b) -> [a] -> [b]
    

    因此,如果您可以编写一个测试一个值的函数,无论它是否存在于第二个列表中,您可以使用map将该函数应用于 all 第一个列表的元素:

    step1 :: Eq a => [a] -> [a] -> [Bool]
    step1 xs ys = map checkOne xs
      where checkOne x = _fillInTheBlank
    

    _fillInTheBlank位称为"空洞" - 您应该在那里实际编写正确的代码!)

    第二步是检查[Bool]以查看是否所有元素都是True。如果是,则返回True,如果至少有一个是{false,则返回False。这也有标准功能:

    -- Returns `False` if any element of the list is `False`, `True` otherwise.
    and :: [Bool] -> Bool
    

    现在:

    listCheck :: Eq a => [a] -> [a] -> Bool
    listCheck xs ys = and (map checkOne xs)
      where checkOne x = _fillInTheBlank
    
    map :: (a -> b) -> [a] -> [b]
    -- Write your own version of `map`
    
    
    and :: [Bool] -> Bool
    -- Write your own version of `and`
    

    请注意我已完成的工作:我已将问题拆分为较小的部分,我可以使用mapand等函数解决这些问题。其他情况。这就是你应该拍的东西。

答案 3 :(得分:-1)

如果您的目标是比较每个列表的第n个元素,那么您已经非常接近了。唯一的问题是你是模式匹配,将两个列表分成头/尾,然后就好像你没有,再次调用headtail

listCheck :: (Eq a, Eq b) => [(a,b)] -> [(a,b)] -> Bool
listCheck xs ys
    | xs == [] = True
    | fst (head xs) /= fst (head ys) = False
    | snd (head xs) /= snd (head ys) = False
    | otherwise = listCheck (tail xs) (tail ys)

这远非最优雅的做事方式,但它是我能找到的最接近你想要写的东西。