如何在Haskell中使用非互斥守卫?

How to use non mutually exclusive guards in Haskell?

如有任何帮助,我们将不胜感激。

我正在尝试在 Haskell 中编写一个函数来查找三个数字中有多少个大于所述三个数字的平均值。

问题是,我正在尝试使用守卫来增加“总和”,但我假设守卫只会去满足第一个条件的条件。有更好的方法吗?

这是我的代码:

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage x y z | aboveAverage x = sum + 1
                          | aboveAverage y = sum + 1
                          | aboveAverage z = sum + 1
                          where
                            aboveAverage a = a > div (x+y+z) 3
                            sum = 0

您可以总结条件并将 Bool 转换为 Int fromEnum :: Enum a => a -> Bool:

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage x y z = sum (map <strong>(fromEnum . (avg <))</strong> [x, y, z])
    where avg = div (x+y+z) 3

或作为 length 一起工作:

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage x y z = length (filter (avg <) [x, y, z])
    where avg = div (x+y+z) 3

是的,只是写的不一样,如

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage x y z = aboveAverage x +
                            aboveAverage y +
                            aboveAverage z 
                          where 
                            avg = div (x+y+z) 3
                            aboveAverage a 
                               | a > avg   = 1
                               | otherwise = 0

在expression-oriented编程中,我们不设置和改变全局变量,我们安排表达式具有相同的最终预期值。

现在您可以调整和简化。特别是,一种不太老套的方法是

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage x y z = length $
                            aboveAverage x ++
                            aboveAverage y ++
                            aboveAverage z
                          where 
                            avg = div (x+y+z) 3
                            aboveAverage a = [a | a > avg]
                            x & f = f x

作为一个选项,这转化为一个很好的列表理解。

或者如果你喜欢的话,可以让它更复杂、更迟钝、更难读。