繁体   English   中英

Haskell位置定义“(使用'/'不会引起(分数整数)实例”)

[英]Haskell Location Definition “No instance for (Fractional Int) arising from a use of ‘/’”

我正在尝试创建的函数的本地定义中收到错误“ 由于使用'/'而导致的(Fractional 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

错误被标记在最后一行。

谢谢。

您正在比较a (这是一个Int )和average (这是Fractional a => a )。 由于(>) :: a -> a Bool ,GHC假定average也是Int ,这是行不通的。 您需要将average更改为Int (例如,通过round ),或者将abc更改为DoubleFloat

您还可以比较整数。 这个想法是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

这是您想到的解决方案的更干净的版本:

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

我设法通过在与平均值进行比较的任何参数之前添加“ fromIntegral”来解决此问题。

新的(有效的)代码:

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

看起来有点凌乱/麻烦,所以如果有人有其他建议(更清洁),请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM