使用"area"时没有(Fractional Int)的实例

Mic*_*hav 2 recursion haskell types functional-programming casting

我是Haskell的新手,我正在编写一个计算函数极限的程序.所以给出两个列表ab,增量dx = 0.001和整合的限制lr,我想递归地计算与方程的曲线下面积: a1(x)^b1 + a2(x)^b2 + ... + an(x)bn这里x是所有的值lr用的增量dx在每个值之间.我猜技术部分并不重要,但它有助于阅读代码:

import Text.Printf (printf)

-- This function should return a list [area].
solve :: Int -> Int -> [Int] -> [Int] -> [Double]
solve l r x y = [area l r x y]

area l r a b = if (l < r)
            then (calc l a b) * 0.001 + (area (l + 1) r a b)
            else (calc r a b) * 0.001


calc n (a:arest) (b:brest) = (fromIntegral(n) ^^ b) * fromIntegral(a) + (calc n arest brest)
calc n [] [] = 0


--Input/Output.
main :: IO ()

main = getContents >>= mapM_ (printf "%.1f\n"). (\[a, b, [l, r]] -> solve l r a b). map (map read. words). lines
Run Code Online (Sandbox Code Playgroud)

我没有得到上述代码的错误,但一旦我更改area (l + 1) r a barea (l + 0.001) r a b我收到以下错误消息:

No instance for (Fractional Int) arising from a use of `area'
Run Code Online (Sandbox Code Playgroud)

我尝试创建一个新类,并且是一个抽象类型但是没有用,还有其他任何想法吗?

CR *_*ost 7

所以问题在于它Int不是一种Fractional类型.换句话说,它没有名为0.001[note 1]的值,但是您已经请求Haskell在代码中为您提供这样的值.

您正在发出此请求,因为它0.001(+)使用另一个类型的参数(在本例中l)提供给函数Int.这是一个问题,因为函数有类型(+) :: (Num a) => a -> a -> a:换句话说,有很多不同的函数(+)都具有类型a -> a -> a; 其中一个函数存在aNum类型类中的每个类型.

因为我们知道函数的一个参数是a Int,所以我们使用了特定的函数(+) :: Int -> Int -> Int.这就是为什么l + 0.001变得奇怪.

至于解决问题:你可能想要lr成为一个类型Double(他们是一个数字可以在哪里左右边界?)但如果你确定他们必须是Ints然后你可能想写fromIntegral l + 0.001.

款式侧面说明:在Haskell括号中始终只是分组/优先,功能设置优先,运营商这比特殊形式(优先级较高的高let,case,if,do),功能应用上始终左结合或"贪婪NOM":功能吃掉前面的任何东西.你写的:

(fromIntegral(n) ^^ b) * fromIntegral(a) + (calc n arest brest)
Run Code Online (Sandbox Code Playgroud)

可能写得更好:

fromIntegral a * fromIntegral n ^^ b + calc n arest brest
Run Code Online (Sandbox Code Playgroud)

括号周围calc是没有必要的(因为像+运营商具有比功能的应用程序的优先级低),也不是围绕括号na(因为那些子表达式是不可分割的块; fromIntegral(n)是相同的fromIntegral (n)是相同的fromIntegral n).

  1. 正如@dfeuer在下面提到的:偷偷地,当你写0.001它时没有明确的类型; 相反,它被转换为fromRational 0.001内部,后者0.001是确定类型的确定值Rational,就像你写4它时被转换为fromInteger 4后者4是确定类型的确定值Integer.问题实际上是没有fromRational函数Int,因为Int它不是Fractional定义的类型类的一部分fromRational.并且它不是该类型类的一部分,因为语言设计者更喜欢将一个错误归结为一个分数的无声舍入/丢弃.