the*_*lim 0 haskell functional-programming
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| a && b && c >= m = 3
| a && b >= m = 2
| b && c >= m = 2
| a && c >= m = 2
| a || b || c >= m = 1
| otherwise = 0
where m = a + b + c
Run Code Online (Sandbox Code Playgroud)
请问为什么这段代码没有运行,我收到了很多我不明白的错误
你写下你的代码:
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| a && b && c >= m = 3
| a && b >= m = 2
| b && c >= m = 2
| a && c >= m = 2
| a || b || c >= m = 1
| otherwise = 0
where m = a + b + cRun Code Online (Sandbox Code Playgroud)
我在这里用粗体表示一个案例,但错误适用于所有这些案例.你写作条件a && b && c >= m.对于Haskell来说,这意味着你可以这样写a && b && (c >= m).现在(&&)是一个运算符,它将两个布尔值作为操作数,并计算这两个布尔值.但操作数不是布尔.c >= m是一个布尔值,但a并b没有布尔值.
所以我们必须在所有操作数上编写条件,例如:
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| a >= m && b >= m && c >= m = 3
| a >= m && b >= m = 2
| b >= m && c >= m = 2
| a >= m && c >= m = 2
| a >= m || b >= m || c >= m = 1
| otherwise = 0
where m = a + b + cRun Code Online (Sandbox Code Playgroud)
所以现在我们有了布尔值,程序将编译,但它仍然是语义上的.平均值是元素之和除以元素数量.元素的数量是3,所以我们应该将它除以3.由于除数可能会导致数值误差,并且意味着我们必须在浮点世界中工作,因此将我们与之比较的元素乘以3会更安全,因此:
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
| a3 >= m && b3 >= m && c3 >= m = 3
| a3 >= m && b3 >= m = 2
| b3 >= m && c3 >= m = 2
| a3 >= m && c3 >= m = 2
| a3 >= m || b3 >= m || c3 >= m = 1
| otherwise = 0
where m = a + b + c
a3 = 3 * a
b3 = 3 * b
c3 = 3 * cRun Code Online (Sandbox Code Playgroud)
现在它有效,但它仍然不优雅:它需要五名警卫来检查条件的数量,总共十二次比较.因此,这将是相当低效的.
一个更好的想法可能是转换True到1和False到0,我们可以用这样做bool catamorphism功能:bool :: a -> a -> Bool -> a.如果我们建造它像bool 0 1那么我们有一个转换功能False来0,并True到1,我们就可以写这样的:
import Data.Bool(bool)
howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c = booltoint (3*a >= m)
+ booltoint (3*b >= m)
+ booltoint (3*c >= m)
where m = a + b + c
booltoint = bool 0 1Run Code Online (Sandbox Code Playgroud)
它可以进一步改进,但我把它留作练习.
| 归档时间: |
|
| 查看次数: |
1261 次 |
| 最近记录: |