2个数据列表比较Haskell

时间:2017-02-26 20:13:32

标签: haskell haskell-stack

我在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]

1 个答案:

答案 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。