从List中删除元素并将其替换为新值

时间:2014-03-13 13:59:26

标签: list haskell

所以我有一个电影评级列表,如果新用户对电影评分,它会被添加到列表中。但是,如果现有用户已对其进行评级,则再次对其进行评级将导致旧评级更改为新评级。到目前为止,这是我的代码:

rateFilm :: String -> String -> Int -> [Film] -> [Rating]
rateFilm _ _ _ []                   = []
rateFilm user title number (x:xs)   = if title == name then do
                                        if user == existingUser then do
                                            removeItem (user,number) ratings
                                            ratings ++ [(user,number)]
                                        else do 
                                            ratings ++ [(user,number)]
                                else  do
                                    rateFilm user title number xs
                                where   (name, director, year, ratings) = x
                                        (existingUser,score)            = getUser user ratings

removeItem :: Rating -> [Rating] -> [Rating]
removeItem _ [] = []
removeItem x (y:ys) | x == y    = removeItem x ys
                | otherwise = y : removeItem x ys

这部电影的信息是:

[("Blade Runner","Ridley Scott",1982,[("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4)]),
 ("The Fly","David Cronenberg",1986,[("Megan",4),("Fred",7),("Chris",5),("Ian",0),("Amy",5)]),
 ("Psycho","Alfred Hitchcock",1960,[("Bill",4),("Jo",4),("Garry",8),("Kevin",7),("Olga",8),("Liz",10),("Ian",9)]),
 ("Body Of Lies","Ridley Scott",2008,[("Sam",3),("Neal",7),("Kevin",2),("Chris",5),("Olga",6)])]

当新用户添加评级时,它很好,输出将如下:

rateFilm "Alex" "Blade Runner" 8 testDatabase1
[("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Alex",8)]

但是,当现有用户执行此操作时,会发生以下情况:

rateFilm "Amy" "Blade Runner" 8 testDatabase1
[("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Amy",8),
("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Amy",8),
("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Amy",8),
("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Amy",8),
("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Amy",8),
("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Amy",8),
("Amy",6),("Bill",9),("Ian",7),("Kevin",9),("Emma",4),("Sam",5),("Megan",4),("Amy",8)]

关于为什么和/或如何修复它的任何想法?非常感谢。

1 个答案:

答案 0 :(得分:3)

  1. 你真的,真的不想在列表monad上运行,除非你知道那里发生了什么。列表monad用于非确定性计算。请参阅wikibook sectionapplicative section of the typeclassopedia
  2. 您想从评分中删除(existingUser, score)而不是(user, number)
  3. 总而言之,我们获得了rateFilm的以下内容:

    rateFilm user title number (x:xs)   =
        if title == name then
            if user == existingUser then
                removeItem (user,score) ratings ++ [(user,number)]
            else
                ratings ++ [(user,number)]
        else
            rateFilm user title number xs
        where   (name, director, year, ratings)  = x
                (existingUser, score)            = getUser user ratings