[英]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 ~ Person
和b ~ [Book]
以及交换参数之后,它几乎具有正确的类型。 由于您想要[Book]
而不是Maybe [Book]
,因此可以将整个内容包装在fromMaybe中 ,结果是:
books db = fromMaybe [] . flip lookup db
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.