List 比较haskell中的元组列表
好的,我对Haskell非常陌生,因为我今天早上开始学习,我的任务是获取两个元组列表[(“s”,1)…],如果它们包含所有相同的元素,则返回true,否则返回false。 到目前为止,我正在考虑从列表1中获取第一个元素,并将其与列表2中的所有元素进行比较,然后对所有元素执行该操作,然后返回true或false。我不知道如何记录所有的布尔人,如果有一个错误,这很容易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
|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)
这远不是最优雅的做事方式,但它是我能找到的最接近你似乎想写的东西。我总是建议新手解决这个问题的方式是:
-- 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`