newtype Name = Name String deriving (Show)
newtype Age = Age Int deriving (Show)
newtype Weight = Weight Int deriving (Show)
newtype Person = Person (Name, Age, Weight) deriving (Show)
type Gym = [Person]
isAdult :: Person -> Bool
isAdult (Person (_, Age a, _)) = a > 18
w = Person (Name "Lee", Age 30, Weight 120)
p = Person (Name "John" , Age 65, Weight 80)
updateWeight :: Person -> Int -> Person
updateWeight (Person (n, a, Weight w)) b = Person (n, a, Weight $ w + b)
getWeight :: Person -> Int
getWeight (Person (a, b, Weight c)) = c
getAge :: Person -> Int
getAge (Person (a, Age b, c)) = b
我现在正想着尝试在两个年龄段内找到健身房里人的平均体重。
到目前为止我已经
了getAverage:: Gym -> (Int, Int) -> Int
getAverage a (b,c) = sum . map getWeight . filter ((b >= age && c <= age) || (b <= age && c >= age))
where
age = getAge a
答案 0 :(得分:2)
你所拥有的是近在咫尺,但并不完全在那里。我建议将问题分解为子表达式,并使用where
或let
本地绑定来更清楚地说明您要执行的操作:
getAverage :: Gym -> (Int, Int) -> Double
getAverage gym (minAge, maxAge) = fromIntegral total / fromIntegral count
where
isInAgeRange person = minAge <= age && age <= maxAge where age = getAge person
validPeople = filter isInAgeRange gym
total = sum $ map getWeight validPeople
count = length validPeople
从这一点开始,您可以将这些行中的一些组合起来以缩短代码,但这非常易读,它不会受到许多效率问题的困扰(尽管您可以同时计算总和和计数)一个花哨的折叠,并没有太多的线来写,因为它。