List 比较haskell中的元组列表

List 比较haskell中的元组列表,list,haskell,functional-programming,tuples,List,Haskell,Functional Programming,Tuples,好的,我对Haskell非常陌生,因为我今天早上开始学习,我的任务是获取两个元组列表[(“s”,1)…],如果它们包含所有相同的元素,则返回true,否则返回false。 到目前为止,我正在考虑从列表1中获取第一个元素,并将其与列表2中的所有元素进行比较,然后对所有元素执行该操作,然后返回true或false。我不知道如何记录所有的布尔人,如果有一个错误,这很容易 |head list1 =/ elementList2 = False 但我只是混淆了我自己,到目前为止,我已经定义了这个列表 l

好的,我对Haskell非常陌生,因为我今天早上开始学习,我的任务是获取两个元组列表[(“s”,1)…],如果它们包含所有相同的元素,则返回true,否则返回false。 到目前为止,我正在考虑从列表1中获取第一个元素,并将其与列表2中的所有元素进行比较,然后对所有元素执行该操作,然后返回true或false。我不知道如何记录所有的布尔人,如果有一个错误,这很容易

|head list1 =/ elementList2 = False
但我只是混淆了我自己,到目前为止,我已经定义了这个列表

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)]是相等的。列表的顺序是不能更改的。

我认为以列表开头并使用它创建一个相等函数是合理的。使用中的
any
all
与尾部进行比较

因为这是一个大学练习,我想你不想得到答案;-)

如果列表元素是完全有序的,这将很好地工作,通常情况下是字符串、数字等(当然还有这些元素的元组)


如果你的元素没有排序规则,事情会变得更加困难,但我认为你不会经常遇到这种情况。

如果你的目标是比较每个列表的第n个元素,那么你已经非常接近了。唯一的问题是,您正在进行模式匹配,以将两个列表分离为head/tail,然后再调用
head
tail

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)

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

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

  • 通过使用标准库函数寻找解决问题的方法
  • 当您在这方面取得成功时,请为您使用的每个库函数编写您自己的版本
  • 在这种情况下,您对所想内容的描述可以精细化为#1风格的解决方案。让我们引用一下:

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

    在这里,不要只考虑对第一个元素执行相同的操作,而是将对所有元素执行相同的操作作为解决方案的一个步骤。有一个标准函数可以捕获此模式:

    -- 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
    将该函数应用于第一个列表的所有元素:

    step1 :: Eq a => [a] -> [a] -> [Bool]
    step1 xs ys = map checkOne xs
      where checkOne x = _fillInTheBlank
    
    (填充空格的
    \u fillinblank
    位称为“孔”-您应该在其中实际写入正确的代码!)

    第二步是检查
    [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`
    

    请注意我所做的:我将问题分成了几个较小的部分,每个部分都可以通过
    map
    以及
    等函数来解决,这些函数在许多其他情况下都很有用。这正是你应该努力的方向。

    我的想法是,你要通过列表检查。你能解释一下“如果它们比较相同的元素,则返回true,否则返回false”是什么意思吗?你的意思是,如果它们包含完全相同的元素,不管顺序如何,它都应该返回true吗?还是相同的元素以相同的顺序排列?或者列表之间是否至少有一个元素是相同的?请准确一点。听起来你想要
    listCheck=(==)
    listCheck=Data.List.isPrefixOf
    当你可以进行模式匹配时,不要使用
    head
    tail
    。应该避免使用部分函数,尤其是初学者……特别是如果这会诱使你将它们用在可能是空的列表上。正如我所说的,这不是做事情的最佳方式,但似乎最接近问题中提出的方法。如果我打算从头开始重新实现这个函数,它将是完全不同的:类似于
    listCheck=(and.)。zipWith(=)
    ,或
    列表检查=(==)
    ,如果不需要短路行为。您可能指的是
    ,而不是
    全部
    ?虽然
    所有pred
    当然比
    和更受欢迎。map pred
    。您上一段代码中的
    列表检查中是否有括号错误?@Bergi:oops,是的,我的意思是
    。但是我没有看到任何括号错误。啊,是的,那是一样的。我原以为会出现类似于
    all(…checkOne)xs
    (关闭参数发生变化)的情况,但在这种情况下,
    map
    放错了位置。
    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`