我在haskell中有2个数据列表,每个列表包含一个id attribut。我想比较两个列表并返回第一个列表中的所有数据对象,但不返回第二个列表。
type IDLibrary = Int
type Location = String
type Author = String
data Book = Book IDLibrary Author deriving Show
data Library = LibraryBook IDLibrary Location deriving Show
book1 = Book 1 "Anthony C"
library1 = LibraryBook 2 "Alaska"
listB :: [Book]
listB = [book1]
listL :: [Library]
listL = [library1]
答案 0 :(得分:1)
您可以使用intersectBy
中的\\
和Data.List
。
使用intersectBy
您将创建常用元素列表,然后使用\\
删除列表中的元素。
期望结果的数学术语是一组在另一组中的相对补充,因此我将如何称之为主函数。
注意:我为 Book 定义了 Eq 实例,其中平等意味着id的平等,但这只是为了<的好处EM> ELEM 。如果该定义不符合您的需求,则将删除中的 elem 替换为检查其中的ID的内容。
导入Data.List 仅适用于 intersectBy 功能
import Data.List
type IDLibrary = Int
type Location = String
type Author = String
data Book = Book IDLibrary Author deriving Show
data Library = LibraryBook IDLibrary Location deriving Show
instance Eq Book where
(==) (Book id _) (Book id' _) = id == id'
listB :: [Book]
listB = [Book 1 "Anthony C", Book 3 "David Weber"]
listL :: [Library]
listL = [LibraryBook 1 "Alaska", LibraryBook 2 "Majorka"]
relativeComplement :: [Book] -> [Library] -> [Book]
relativeComplement xs ys = xs `remove` common xs ys
remove :: [Book] -> [Book] -> [Book]
remove xs ys = filter (not . (`elem` ys)) xs
common :: [Book] -> [Library] -> [Book]
common xs ys = intersectBy sameID xs (intoBooks ys)
sameID :: Book -> Book -> Bool
sameID (Book id1 _) (Book id2 _) = id1 == id2
intoBooks :: [Library] -> [Book]
intoBooks = map turnIntoBook
where turnIntoBook (LibraryBook id _) = Book id ""
输出:
[Book 3&#34; David Weber&#34;]
PS绝不是我的代码质量很高,我也在学习Haskell。