1
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
4

1 回答 1

2

你所拥有的很接近,但并不完全在那里。我建议将问题分解为子表达式并使用wherelet本地绑定以更清楚您想要做什么:

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

从这一点开始,你可以结合其中的一些行来缩短代码,但这非常可读,它不会遇到很多效率问题(尽管你可以用花哨的折叠同时计算总和和计数),并且不需要太多的行来编写它。

于 2013-10-04T12:56:01.487 回答