Haskell - 如何在对列表中获取列表的元素?

时间:2014-09-28 21:22:44

标签: haskell

我有一个结构

type MyDatabase = [ (String, [String]) ]

鉴于第一个字符串,我想通过数据库找到匹配的术语,然后返回随附的列表。

我有

lookup :: MyDatabase -> String -> [String]
lookup dataBase str = [ list | (label, [list]) <- dataBase, str == label ]

每次都会返回一个空列表。

2 个答案:

答案 0 :(得分:4)

你几乎拥有列表理解权,如果你拥有数据库[("foo", ["bar"])]并尝试lookup [("foo", ["bar"])] "foo",这将返回一些内容。如果您的数据库是[("foo", ["bar", "baz"])],它将无效。这是因为您在数据库中的元素上具有模式匹配,这些元素只有一个元素作为其关联的字符串列表,因此如果键没有关联元素或者它有许多关联元素,则它不起作用。您可以通过将其更改为(label, list) <- dataBase来轻松解决此问题。

此外,您可以改为使用内置于lookup的{​​{1}}函数,其类型为

Prelude

然后你可以专门为你的类型

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

答案 1 :(得分:3)

你需要做一些调整:

lookup :: MyDatabase -> String -> [String]
-- lookup ...       = [ list | (label, [list]) <- dataBase, str == label ]
lookup dataBase str = [ s    | (label,  list ) <- dataBase, str == label 
                             , s <- list ]

如果您的数据库中有相同标签下的重复条目,您将根据您的类型签名将所有值集合在一个字符串列表中。

如果您只想要第一个匹配的条目,则只需输入第一个匹配的条目,然后使用concat将其打开:

lookup dataBase str = concat . take 1 $
                      [ list | (label,  list ) <- dataBase, str == label]