基本的haskell:找到两个值之间的平均值

时间:2013-10-04 12:40:46

标签: haskell

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

1 个答案:

答案 0 :(得分: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

从这一点开始,您可以将这些行中的一些组合起来以缩短代码,但这非常易读,它不会受到许多效率问题的困扰(尽管您可以同时计算总和和计数)一个花哨的折叠,并没有太多的线来写,因为它。