I have just started learning Haskell and have got stumped on how to add a rating to a custom data type.
The data type I'm using has a name, a year and a tuple (userName and their rating), it looks like:
data Wine = Wine String Int [Rating] deriving (Eq,Ord,Show,Read)
type Rating = (String, Int)
I wanted to allow a user to rate a given wine from a database, stored as [Wine] but cant figure out how to to it. Any pointers or suggestions would be greatly appreciated! Thanks.
Why not use record syntax ?
data Wine = Wine {
wineName :: String,
wineYear :: Int,
wineRatings :: [Rating]
}
rateWine :: Wine -> Rating -> Wine
rateWine wine rating = wine { wineRatings = rating : wineRatings wine }
I hope this solves your problem:
addRating :: Wine -> Rating -> Wine
addRating (n, y, rs) r = (n, y, r:rs)
In addition to the problem of adding a rating to a single wine (solved nicely by the other posters), there's also two more tasks that need to be done:
findWineIndex :: String -> Int -> [Wine] -> Maybe Int
- I'm using Maybe Int as the result to allow for the possibility that you're looking for a Chateau Briand 2025, or something like that. replaceWineInList :: Int -> Wine -> [Wine] -> [Wine]
which takes an index, an updated wine and the original database, and which returns the updated wine database. However, managing the index explicitly is not the nicest way you can do this! (Not to mention that is inefficient as you'll be traversing the list twice, slightly messy with the Maybe
handling and, dare I say it, the imperative way :)
You could also try defining a function updateFirstThat :: (a -> Bool) -> (a -> a) -> [a] -> [a]
taking a predicate and an update function which applies the update to the first element that satisfies the predicate. An example use would be updateFirstThat (>3) (*2) [1..6]
which should evaluate to [1,2,3,8,5,6]
.
I hope you can puzzle together a solution with these bits and pieces, otherwise just ask for a few more hints!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.