繁体   English   中英

Haskell —列表内的元组内的列表的列表理解

[英]Haskell — List Comprehension with Lists inside a Tuple inside a List

我有:

type Person     = String
type Book       = String
type Database   = [(Person,[Book])]

我正在尝试定义一个函数:

books :: Database -> Person -> [Book]

接受1)一个元组列表(包含一个字符串和一个字符串列表2)一个字符串名称

并返回一个字符串列表(即数据库中的书籍)

我想使用列表理解,但是我不知道如何访问数据库列表内部元组中的列表中的元素。

有什么想法吗?

示例数据库如下所示:

db = [("Bob", ["Red Riding Hood", "Alice in Wonderland"]), ("Carol", ["Game of Thrones"])]

如果我要说“ Carol”,它应该返回[“权力的游戏”]。

由于您具有关联列表,因此可以使用lookup功能。 几乎完全可以按照您想要的方式工作:

getVal :: Database -> String -> Maybe [String]
getVal  = lookup

唯一的区别是它返回Maybe但IMHO是正确的行为,请考虑如果在查询数据库时没有值,会发生什么情况?

由于您要使用模式匹配,因此这里是lookup的来源

lookup                  :: (Eq a) => a -> [(a,b)] -> Maybe b
lookup _key []          =  Nothing
lookup  key ((x,y):xys)
    | key == x          =  Just y
    | otherwise         =  lookup key xys

还是你的情况

getVal :: Database -> String -> [String] --Avoids a Maybe if you want
getVal _key []          =  []
getVal  key ((x,y):xys)
    | key == x          =  y
    | otherwise         =  getVal key xys

正如其他张贴者所说, lookup是前往此处的方法:这是在关联列表中搜索内容的标准过程。

也就是说,使用列表理解的解决方案

books :: Database -> Person -> [Book]
books db authorName = [book | (author, bookName) <- db,
                              author == authorName
                              book <- bookName]

(author, bookName)取出(author, bookName)元组,丢弃与作者不匹配的元组。 如果是,则将该作者的书添加到结果中。

再次,这为标准库中已经存在的功能实现了一种变通方法,并且一般来说可读性较低。 确实,使用lookup

我不会使用列表理解来实现该功能-列表理解更适合于构建列表。

您正在寻找的是Prelude函数查找

lookup :: Eq a => a -> [(a, b)] -> Maybe b

如您所见,如果a ~ Personb ~ [Book]以及交换参数之后,它几乎具有正确的类型。 由于您想要[Book]而不是Maybe [Book] ,因此可以将整个内容包装在fromMaybe中 ,结果是:

books db = fromMaybe [] . flip lookup db

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM