簡體   English   中英

比較Haskell中的元組列表

[英]Comparing a List of tuples in haskell

好的,我是Haskell的新手,因為我從今天早上開始學習,並被要求接受2個元組[[“ s”,1)..]的列表,如果它們都具有相同的元素,則返回true,否則返回假。 到目前為止,我正在考慮從列表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)]相等。 列表的順序無法更改。

我認為以列表的開頭並使用它創建一個相等函數是合理的。 使用列表庫中的 anyall與尾進行比較。

由於這是一次大學練習,我想您不希望得到答案;-)

listCheck l1 l2 = sort l1 == sort l2

如果列表元素是完全有序的,它將很好地工作,在字符串,數字等(以及此類元素的自然元組)的通常情況下,它們將是正常的。

如果您的元素沒有排序,事情就會變得困難得多,但我認為您不會經常遇到這種情況。

我總是建議新手解決此問題的方法是:

  1. 尋找使用標准庫函數解決問題的方法。
  2. 成功完成后,請為使用的每個庫函數編寫自己的版本。

在這種情況下,您對自己的想法的描述可以精煉成#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

_fillInTheBlank位稱為“孔”,您應該在那里實際編寫正確的代碼!)

第二步是檢查[Bool]以查看所有元素是否均為True 如果為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 ,將在其他許多情況下是有用的。 那就是你應該拍攝的。

如果您的目標是比較每個列表的第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)

這遠不是最優雅的做事方式,而是我所能找到的與您似乎想寫的東西最接近的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM