首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >haskell中的体重指数程序

haskell中的体重指数程序
EN

Stack Overflow用户
提问于 2010-06-12 07:43:45
回答 5查看 1.1K关注 0票数 1

我正试着用Haskell写一个简单的程序来确定一个人的体重指数。

下面是我写的内容:

代码语言:javascript
复制
type Height = Float
type Weight = Float
type PeopleStats = [(String, Height, Weight)]

还有..。

代码语言:javascript
复制
bmi :: Height -> Weight -> Float
bmi heightCm weightKg = weightKg/(heightCm)^2

healthy :: Height -> Weight -> Bool
healthy heightCm weightKg | 25 > index && 18 < index = True
                          | otherwise                = False
  where index = bmi heightCm weightKg

到目前为止,函数" healthy“可以计算某人的体重指数,函数"healthyPeople”返回一个布尔语句,确定此人的体重指数是否在健康人认为正常的范围内。

我想写一个名为"healthyPeople“的函数。

代码语言:javascript
复制
healthyPeople :: PeopleStats -> [String]

此函数需要获取一个健康列表,并从“PeopleStats”函数返回一个被认为是“健康”的人的姓名(字符串)列表。

例如:

如果我输入[("Lee", 65, 185), ("Wang", 170, 100), ("Tsu", 160, 120)],我将从"healthy“中的布尔函数中获得其BMI返回true的人的名字的列表。

请帮帮我!

EN

回答 5

Stack Overflow用户

发布于 2010-06-12 08:23:52

首先,我认为您可能想要将bmi定义为:

代码语言:javascript
复制
bmi :: Height -> Weight -> Float
bmi heightCm weightKg = weightKg/(heightCm/100)^2

因为公式使用的是以米为单位的高度。

现在,这里是使用helper函数的一步一步的方法。我定义了一个类型:

代码语言:javascript
复制
type PersonStats = (String, Height, Weight)

以及该类型上的一些函数:

代码语言:javascript
复制
healthyPerson :: PersonStats -> Bool
healthyPerson (name, h, w) = healthy h w

getName :: PersonStats -> String
getName (name, h, w) = name

有了这些,最后的函数就变得微不足道了:

代码语言:javascript
复制
healthyPeople :: PeopleStats -> [String]
healthyPeople people = map getName $ filter healthyPerson people

或者用无点符号表示:

代码语言:javascript
复制
healthyPeople :: PeopleStats -> [String]
healthyPeople = map getName . filter healthyPerson

首先从列表中筛选出健康的人,然后将统计数据列表映射到姓名列表。

如果你使用lambdas,你可以在没有帮助器的情况下一次性表达整个函数。

票数 5
EN

Stack Overflow用户

发布于 2010-06-12 08:29:16

这里有一个名为filter的标准Haskell函数,它完全(好吧,几乎是)完成了您想要做的事情。它的类型为(a -> Bool) -> [a] -> [a],即接受一个谓词和一个列表,并返回满足该谓词的成员。

您不能将其直接应用于PeopleStats,因为类型不匹配,但是编写一个函数将两者连接起来并不难:

代码语言:javascript
复制
healthyPerson :: (String, Height, Weight) -> Bool
healthyPerson (_, h, w) = healthy h w

healthyPeople :: [(String, Height, Weight)] -> [String]
healthyPeople people = map name $ filter healthyPerson people
  where name (s, _, _) = s

这就是你想要的。

票数 2
EN

Stack Overflow用户

发布于 2010-06-12 08:16:53

首先,请注意您对BMI的定义是错误的-您需要将厘米转换为米:

代码语言:javascript
复制
bmi heightCm weightKg = weightKg/(heightCm/100)^2

解决了这个问题后,我想出了以下几点:

代码语言:javascript
复制
healthyPeople :: PeopleStats -> [String]
healthyPeople [] = []
healthyPeople ((name, height, weight):xs) | healthy height weight = name : healthyPeople xs
                                          | otherwise = healthyPeople xs

这是相当直接的。它使用list-based recursion来递归列表中的所有元素,并使用类似于您在healthy函数中使用的卫士来根据列表顶部的人是否健康来切换行为。如果它们是健康的,那么它们的名字就是concatted with,这是处理列表其余部分的结果。

下一次,你应该试着自己解决这个问题,然后寻求帮助(并展示你尝试过的东西)。你会学到更多!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3026907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档