haskell如何检查两个元组列表相等并采取联合

cyn*_*ynn 5 tuples list

我是哈斯克尔的一个新的自我瘦身者.首先,我想编写一个函数来检查两个元组列表是否相等.每个元组都有一个键和值

其次,我想要一个函数来联合两个元组列表

我尝试了几种方法并尝试了很多次,但似乎无法满足我的要求.谁能帮助我?提前致谢.

ƛƛƛ*_*ƛƛƛ 5

由于a只是其中的一员Eq,因此排序或分组不是一种选择.

import Data.List(nub, (\\))
import Data.Monoid(getSum)

type Times = Int
type Lis a = [(a,Times)]

lisEqual :: Eq a => Lis a -> Lis a -> Bool
lisEqual xs xs' = length xs == length xs' && xs \\ xs' == []

lisSum :: Eq a => Lis a-> Lis a-> Lis a
lisSum xs xs' = fmap f $ getKeys l 
  where
    f x = (,) x (getSum . foldMap (pure . snd) . filter ((x ==) . fst) $ l)                         
    l = xs ++ xs'
    getKeys = nub . fst . unzip
Run Code Online (Sandbox Code Playgroud)


Jon*_*ård 2

我的建议:从一个从两个列表中提取组合键的函数开始:

allKeys :: Eq a => Lis a -> Lis a -> [a]
Run Code Online (Sandbox Code Playgroud)

亦是如此。allKeys [('a',2),('b',2),('c',3)] [('b',2),('a',1),('d',3)]['a','b','c','d']提示:从两个列表中提取所有键,将它们合并到一个列表中,然后从该列表中删除重复项(所有这些任务都有标准函数)。

该函数对于检查相等性和计算总和都很有用:

  • 要检查相等性,只需检查在第一个列表中查找每个键是否给出与在第二个列表中查找相同的结果。
  • 要计算总和,只需将每个键与两个原始列表中的查找总和配对即可。

需要考虑的一件事是:该列表[('a',0)]是否与 相同[]?否则,您应该使用一个查找函数,在第一种情况和第二种情况下返回Maybe Int并给出键“a”。Just 0Nothing

如果这不是家庭作业,请告诉我,我可以给你代码。

编辑:代码!:)

与我通常编写的代码相比,下面的代码稍微简化了,但也没有简化太多。您可能不熟悉几个库函数,包括从 Data.List 导入的 nub (用于删除重复项)。

import Data.List(nub)

type Times = Int
type Lis a = [(a,Times)] 

count :: Eq a => Lis a -> a -> Times
count xs x = case lookup x xs of
  Nothing -> 0 -- x is not in the list
  Just n  -> n -- x is in the list associated with n

-- Extract all keys by taking the first value in each pair
keys :: Lis a -> [a]
keys xs = map fst xs 

-- Extract the union of all keys of two lists
allKeys :: Eq a => Lis a -> Lis a -> [a]
allKeys xs ys = nub (keys xs ++ keys ys)

lisEquals :: Eq a=> Lis a -> Lis a -> Bool
lisEquals xs ys = all test (allKeys xs ys) 
  where
    -- Check that a key maps to the same value in both lists
    test k = count xs k == count ys k

lisSum :: Eq a => Lis a -> Lis a -> Lis a
lisSum xs ys = map countBoth (allKeys xs ys)
  where
    -- Build a new list element from a key
    countBoth k = (k,count xs k + count ys k)
Run Code Online (Sandbox Code Playgroud)