【问题标题】:Haskell Location Definition "No instance for (Fractional Int) arising from a use of ‘/’"Haskell 位置定义“没有因使用‘/’而产生 (Fractional Int) 的实例”
【发布时间】:2014-10-19 12:01:01
【问题描述】:

我收到错误“No instance for (Fractional Int) from a use of '/'”,来自我尝试创建的函数的本地定义内部有多少(三个)给定整数高于所有给定整数的平均值。所以我在函数内部创建了一个局部定义来计算平均值,这样我就可以将它用于警卫检查。我在单独的定义(在另一个文件中)中使用了相同的代码来计算平均值并且它有效。我尝试将“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

错误在最后一行被标记出来。

谢谢。

【问题讨论】:

    标签: function haskell functional-programming


    【解决方案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
    

    【讨论】:

    • 谢谢,这看起来确实是一种更清洁的方式。今天晚些时候我会检查它。
    【解决方案2】:

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

    【讨论】:

    • 您好,感谢您的回复,但这并不能真正回答问题。我需要 a + b + c 除以 3,所以我需要答案是浮点格式。
    • @EM-Creations:抱歉,误读了您的问题。问题在于比较。
    • 我想我已经设法通过在每个参数前面加上“fromIntegral”来修复它,然后再将它与平均值进行比较,谢谢。我会发布决议。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      我已经设法通过在与平均值进行比较的任何参数前添加“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
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多