没有因使用“area”而产生的(Fractional Int)实例
No instance for (Fractional Int) arising from a use of `area'
我是 Haskell 的新手,我正在编写一个计算函数极限的程序。因此,给定两个列表 a
和 b
,一个增量 dx = 0.001
,以及积分的极限 l
和 r
,我想递归计算下面的面积方程式曲线:
a1(x)^b1 + a2(x)^b2 + ... + an(x)bn
其中 x
是 l
和 r
之间的所有值,每个值之间的增量为 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
上面的代码没有错误,但是当我将 area (l + 1) r a b
更改为 area (l + 0.001) r a b
时,我收到以下错误消息:
No instance for (Fractional Int) arising from a use of `area'
我尝试制作一个新的 class 并使 a 成为抽象类型,但这没有用,还有其他想法吗?
所以问题是 Int
不是 Fractional
类型。换句话说,它没有一个叫做0.001
的值[注1],但是你在你的代码中要求Haskell给你这样一个值。
您提出此请求是因为 0.001
被馈送到 (+)
函数并带有另一个类型为 Int
的参数(在本例中为 l
)。这是一个问题,因为函数的类型为 (+) :: (Num a) => a -> a -> a
:换句话说,有很多不同的函数 (+)
都具有类型 a -> a -> a
; Num
类型 class 中的每个类型 a
都存在这些函数之一。
由于我们知道函数的一个参数是 Int
,因此我们使用的是特定函数 (+) :: Int -> Int -> Int
。这就是 l + 0.001
变得奇怪的原因。
至于解决问题:您可能希望 l
和 r
属于 Double
类型(它们是数字可以在何处的左右边界?)但是如果您确定它们必须是 Int
,那么您可能打算写 fromIntegral l + 0.001
。
关于样式的旁注:Haskell 中的括号始终只是 grouping/precedence,函数的优先级高于运算符,运算符的优先级高于特殊形式(let
、case
, if
, do
) 和函数应用总是左结合的或 "greedy nom":函数吃掉它前面的任何东西。你写了什么:
(fromIntegral(n) ^^ b) * fromIntegral(a) + (calc n arest brest)
最好写成:
fromIntegral a * fromIntegral n ^^ b + calc n arest brest
calc
周围的括号不是必需的(因为 + 等运算符的优先级低于函数应用程序), n
和 a
周围的括号也不是必需的(因为那些子-表达式是不可分割的块;fromIntegral(n)
等同于 fromIntegral (n)
等同于 fromIntegral n
)。
- 正如@dfeuer 在下面提到的:秘密地,当你写
0.001
时,它没有明确的类型;相反,它在内部被翻译成 fromRational 0.001
,其中后者 0.001
是确定类型 Rational
的确定值,就像你写 4
时它被翻译成 fromInteger 4
其中后4是定型Integer
的定值。问题实际上是 Int
没有 fromRational
函数,因为 Int
不是定义 fromRational
的 Fractional
类型 class 的一部分.而且它不是那种类型的一部分class,因为语言设计者更喜欢错误而不是沉默的 rounding/dropping 分数。
我是 Haskell 的新手,我正在编写一个计算函数极限的程序。因此,给定两个列表 a
和 b
,一个增量 dx = 0.001
,以及积分的极限 l
和 r
,我想递归计算下面的面积方程式曲线:
a1(x)^b1 + a2(x)^b2 + ... + an(x)bn
其中 x
是 l
和 r
之间的所有值,每个值之间的增量为 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
上面的代码没有错误,但是当我将 area (l + 1) r a b
更改为 area (l + 0.001) r a b
时,我收到以下错误消息:
No instance for (Fractional Int) arising from a use of `area'
我尝试制作一个新的 class 并使 a 成为抽象类型,但这没有用,还有其他想法吗?
所以问题是 Int
不是 Fractional
类型。换句话说,它没有一个叫做0.001
的值[注1],但是你在你的代码中要求Haskell给你这样一个值。
您提出此请求是因为 0.001
被馈送到 (+)
函数并带有另一个类型为 Int
的参数(在本例中为 l
)。这是一个问题,因为函数的类型为 (+) :: (Num a) => a -> a -> a
:换句话说,有很多不同的函数 (+)
都具有类型 a -> a -> a
; Num
类型 class 中的每个类型 a
都存在这些函数之一。
由于我们知道函数的一个参数是 Int
,因此我们使用的是特定函数 (+) :: Int -> Int -> Int
。这就是 l + 0.001
变得奇怪的原因。
至于解决问题:您可能希望 l
和 r
属于 Double
类型(它们是数字可以在何处的左右边界?)但是如果您确定它们必须是 Int
,那么您可能打算写 fromIntegral l + 0.001
。
关于样式的旁注:Haskell 中的括号始终只是 grouping/precedence,函数的优先级高于运算符,运算符的优先级高于特殊形式(let
、case
, if
, do
) 和函数应用总是左结合的或 "greedy nom":函数吃掉它前面的任何东西。你写了什么:
(fromIntegral(n) ^^ b) * fromIntegral(a) + (calc n arest brest)
最好写成:
fromIntegral a * fromIntegral n ^^ b + calc n arest brest
calc
周围的括号不是必需的(因为 + 等运算符的优先级低于函数应用程序), n
和 a
周围的括号也不是必需的(因为那些子-表达式是不可分割的块;fromIntegral(n)
等同于 fromIntegral (n)
等同于 fromIntegral n
)。
- 正如@dfeuer 在下面提到的:秘密地,当你写
0.001
时,它没有明确的类型;相反,它在内部被翻译成fromRational 0.001
,其中后者0.001
是确定类型Rational
的确定值,就像你写4
时它被翻译成fromInteger 4
其中后4是定型Integer
的定值。问题实际上是Int
没有fromRational
函数,因为Int
不是定义fromRational
的Fractional
类型 class 的一部分.而且它不是那种类型的一部分class,因为语言设计者更喜欢错误而不是沉默的 rounding/dropping 分数。