2012-05-02 88 views
1

我想修改數據庫列表中的一個元素添加到評分,我想返回一個修改過的數據庫與新元素。我瞭解Haskell具有不變的東西,但同時我不能完全掌握如何去做。修改和返回列表修改元素

以下是類型:

data Film = Film Director Title Year Ratings 
    deriving (Show,Ord,Eq, Read) 

testDatabase :: [Film] 

我唯一的代碼是:

--addRating :: Rating -> Film -> Film 
--addRating rating (Film name director year ratings)= (Film name director year [(ratings : rating)]) 


--findFilm name = head $ filter (\(Film n _ _ _) -> n == name) testDatabase 

這一發現電影作品很好,但我不能讓addRating工作,即使它工作我仍然不明白如何將它們組合在一起以具有調用的函數來返回具有新評級元素的Film列表。

回答

3

你幾乎擁有了正確的:

addRating rating (Film name director year ratings) 
    = (Film name director year [(ratings : rating)]) 

目前你的代碼:

[(ratings : rating)] 

:操作員輸入a -> [a] -> [a],它需要一個元素,並將其添加到開始的列表,而不是列表的末尾,所以你需要切換你的參數。

另外,語法[x]在像你一樣使用時會創建一個由一個元素組成的列表。如果你在這裏使用它,它會把你創建的列表包裝到另一個列表中,這不是你想要的。

你只需要做一個清單,包括前置到ratings的其餘部分rating的:

(rating : ratings) 
2

這是因爲Porges說,你以錯誤的順序得到ratingratings。您可能會發現記錄語法的方法根據自己的喜好:

data Film = Film {director :: Director, title :: Title, year :: Year, ratings :: Ratings} 
       deriving (Show,Ord,Eq, Read) 

addRating :: Rating -> Film -> Film 
addRating rating film = film {ratings = rating : ratings film} 

這裏,film {director = "Martin Scorsese"}「更新」的director場,也就是表達是指用不同的導演Film,但一切是相同的。但在目前的情況下,您需要輸入舊的ratings字段的內容,因此您需要預先編制ratingratings film。這種聲明類型的方式給出了衍生Show的不同外觀。

0

...我不能讓addRating工作,即使它沒有工作,我仍然不 瞭解如何劃分網格一起有一個函數來調用到 回電影列表它具有新評級的元素。

看起來你希望有一個函數返回新的數據,以一種可以訪問的方式「舊數據曾經是」。

這裏要理解的關鍵是那個就會讓它變成可變數據。

函數式編程提供的一件事是保證數據永遠是相同的。在一種命令式(非功能性)語言中,如果您有多個可能會更改數據的進程,則必須小心不要以意想不到的方式修改彼此的數據。不可變的數據使這成爲一個非問題。

如果你真的想破壞性更新,有辦法做到這一點。但是,可能您要尋找的是State monad,這是一種不帶破壞性更新的「隨身攜帶」狀態的好方法。

0

對「不變的東西」的理解的關鍵在於你不需要修改你得到的東西,你只是創建一個有點不同的「複製」,並返回作爲結果。例如,你有一個包含[1,2,3]的列表l。當你做l ++ [4],你回來[1,2,3,4],l的值並沒有改變

使用與您的電影記錄相同的原則 - 您已經接近。

正如其他人指出的那樣,您在(ratings : rating)表達式中混合了您的類型。要使用:,該元素在前面,列表返回。你可以切換你的類型,但是這會把新的評級放在前面,這可能不是你想要的。另一種方法是使用++,其附加兩個列表。因此,要使用++,您需要從單個元素中創建一個列表,並將其附加到現有評級。

addRating :: Rating -> Film -> Film 
addRating rating (Film name director year ratings) = 
    (Film name director year (ratings ++ [rating]))