从条件数据列表中获取数据

Getting data from data list from conditions

我试图找到更接近 (20.2,-1.00) 并且得分高于 7 的用户。但是我尝试的一切似乎都不起作用,而且我一直被卡住。下面的代码显示了我最近的尝试。任何帮助都会很棒。

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

我没有在作业中看到 distances 计算的确切定义。 所以我创建了两个函数来根据需要进行自定义:

s :: [Double] -> Double
distanceFrom :: (Double, Double) -> User -> Double

然后我创建了满足您的两个条件的函数:

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

那么您只需拨打:

near7 :: [User] -> User
near7 u = minDistance (50.2,-0.4) (filter (scoreHigherThan 7) u)

下面是实现未知 sdistanceFrom 函数的示例:

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: minDistance 使用 foldr(没有显式递归):

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'