Im trying to get the user that is closer to (20.2,-1.00) and has a score higher than 7. However everything i try doesnt seem to work, and i keep getting stuck. The code below shows my most recent attempt. Any help would be great.
data User = User { name :: String
, location :: (Double,Double)
, score :: [Double]
}
user1 = User {name = "BladeBoy", location = (50.45,-1.203),score = [10.2,5.6,7.8]}
user2 = User {name = "Kaslan", location = (60.78,1.003),score = [20,7.6,12.1]}
user3 = User {name = "Ryan", location = (50.0,-0.283),score = [10.2,7.8,7.8]}
users :: [User]
users = [user1,user2,user3]
near7Help :: [(Double, Double)] -> [(Double, Double)]
near7Help (x : xs) = (near7 x ) near7Help >> xs
near7 :: (Double,Double) -> (Double,Double)
near7 x _ = snd . minimum . map (abs . subtract 7 &&& id)
getScores (User _ _ score) = score
-- output user nearest to 50.2,-0.4 and middle score higher than 7
CodePudding user response:
I do not see the exact definition of a distance
and an s
calculation in the assignment.
So I've created two function to customize as needed:
s :: [Double] -> Double
distanceFrom :: (Double, Double) -> User -> Double
Then I created functions fulfilling your two criteria:
scoreHigherThan :: Double -> User -> Bool
scoreHigherThan a u
= s (score u) > a
minDistance :: (Double, Double) -> [User] -> User
minDistance a (x:xs) = minDistance' a xs (distanceFrom a x) x
minDistance' :: (Double, Double) -> [User] -> Double -> User -> User
minDistance' _ [] d u = u
minDistance' a (x:xs) d u
| d' < d = minDistance' a xs d' x
| otherwise = minDistance' a xs d u
where d' = distanceFrom a x
Then all you have to do is call:
near7 :: [User] -> User
near7 u = minDistance (50.2,-0.4) (filter (scoreHigherThan 7) u)
Here's an example of implementing the unknown s
and distanceFrom
functions:
s :: [Double] -> Double
s x = sum x / fromIntegral (length x)
distanceFrom :: (Double, Double) -> User -> Double
distanceFrom (f,g) User {name = b, location = (c,d), score = e}
= (c-f)^2 (d-g)^2
Edit1: The minDistance
using a foldr
(without explicit recursion):
minDistance :: (Double, Double) -> [User] -> User
minDistance a (b:bs) = snd $ foldr (minDistance' a) (distanceFrom a b,b) bs
minDistance' :: (Double, Double) -> User -> (Double, User) -> (Double, User)
minDistance' p u' (d,u)
| d' < d = (d',u')
| otherwise = (d,u)
where d' = distanceFrom p u'