2013-02-03 56 views
0

我:哈斯克爾 - 列表綜合使用列表元組內的列表內

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"])] 

如果我問說「頌歌」,它應該返回[「權力的遊戲」。

回答

3

既然你有一個關聯列表,你可以使用lookup函數。它幾乎作品完全一樣,你想:

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

唯一的區別是,它返回一個Maybe但恕我直言這是正確的行爲,可以考慮,如果你沒有在你的數據庫中的值會發生什麼,當你看了看?

既然你想使用模式匹配這裏是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 
+0

好吧我看到這是如何工作的,但無論如何對我來說這樣做使用列表理解或模式匹配? –

+0

編輯顯示 – jozefg

1

我不會用一個列表理解爲實現該功能 - 列表解析更適合構建列表。

你所尋找的是前奏功能:

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

正如你可以看到它幾乎具有正確的類型,如果a ~ Personb ~ [Book]和交換意見之後。既然你想[Book]回來,而不是Maybe [Book]你可以用整個事情裏面fromMaybe,導致:

books db = fromMaybe [] . flip lookup db 
+0

好的,謝謝! –

2

正如其他海報說,lookup是去這裏的方式:它的標準程序來搜索東西一個關聯列表。

也就是說,使用列表理解

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

它取出(author, bookName)元組逐一丟棄在這裏筆者不匹配的人的解決方案。如果將該作者的書籍添加到結果中。

同樣,這對已經在標準庫中的函數實現了一種解決方法,並且通常它的可讀性較差。真的,使用lookup

+0

是的,這似乎是更好的方式去它,它的工作。 –