Haskell位置定义"使用'/'"没有(Fractional Int)的实例

时间:2014-10-19 12:01:02

标签: function haskell functional-programming

我收到错误“因使用'/'”而导致的(分数Int)没有实例,来自我正在尝试制作的函数中的本地定义有多少(三)给定的整数高于所有给定整数的平均值。所以我在函数内部创建了一个局部定义来计算平均值,这样我就可以用它来进行保护检查。我在一个单独的定义(在另一个文件中)中使用相同的代码来计算平均值并且它可以工作。我已经尝试将“ fromIntegral ”函数调用放在不同的地方,但它不起作用,我哪里出错?

以下是代码:

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
    | a > average && b > average = 2
    | a > average && c > average = 2
    | b > average && c > average = 2
    | a > average = 1
    | b > average = 1
    | c > average = 1
    | otherwise = 0
                where
                average = fromIntegral (a + b + c) / 3

错误正在最后一行标记。

感谢。

4 个答案:

答案 0 :(得分:1)

您要比较aInt}和averageFractional a => a)。自(>) :: a -> a Bool起,GHC认为average也是Int,但不起作用。您需要将average更改为Int(例如通过round)或abc更改为DoubleFloat

答案 1 :(得分:1)

您也可以比较整数。我们的想法是x < (a + b + c)/3等同于3*x < a + b + c

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
    | gti a av && gti b av = 2
    | gti a av && gti c av = 2
    | gti b av && gti c av = 2
    | gti a av = 1
    | gti b av = 1
    | gti c av = 1
    | otherwise = 0
        where 
            av = a + b + c
            gti x m = 3*x > m

答案 2 :(得分:1)

这是您提出的解决方案的更简洁版本:

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
    | a' > average && b' > average = 2
    | a' > average && c' > average = 2
    | b' > average && c' > average = 2
    | a' > average = 1
    | b' > average = 1
    | c' > average = 1
    | otherwise = 0
  where
    average = a' + b' + c' / 3
    a' = fromIntegral a
    b' = fromIntegral b
    c' = fromIntegral c

您可以进一步简化为:

howManyAboveAverage a b c = length (filter (> average) [a', b', c'])
  where
    average = a' + b' + c' / 3
    a' = fromIntegral a
    b' = fromIntegral b
    c' = fromIntegral c

答案 3 :(得分:0)

我设法通过添加&#34; fromIntegral&#34;来解决这个问题。在任何与平均值相比较的参数前面。

新(工作)代码:

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage a b c
    | fromIntegral a > average && fromIntegral b > average = 2
    | fromIntegral a > average && fromIntegral c > average = 2
    | fromIntegral b > average && fromIntegral c > average = 2
    | fromIntegral a > average = 1
    | fromIntegral b > average = 1
    | fromIntegral c > average = 1
    | otherwise = 0
                where
                average = fromIntegral (a + b + c) / 3

它看起来有点乱/笨重所以如果有人有任何其他(更干净)的建议请告诉我。