Haskell 二次求解器 - 错误
Haskell Quadratic solution finder - Error
我在大学里使用 Haskell,我必须做的其中一项练习是创建一个函数,当我给出二次方程的系数时,它会给出二次方程的根,使用之前的函数告诉我有多少解决方案。这是我所做的:
第一个函数,这个很好用:
nRoots :: Float -> Float -> Float -> Int
nRoots a b c | r<0 = 0
| r==0 = 1
| otherwise = 2
where r = b^2-4*a*c
第二个功能,它不起作用:
roots :: Float -> Float -> Float -> [Float]
roots a b c | nRoots==2 = [(-b-sqrt(b^2-4*a*c))/(2*a),(-b+sqrt(b^2-4*a*c))/(2*a)]
| nRoots==1 = [-b/(2*a)]
| otherwise = []
这是我得到的错误:
raizes.hs:8:21:
No instance for (Eq (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from a use of ‘==’
In the expression: nRoots == 2
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
In an equation for ‘roots’:
roots a b c
| nRoots == 2
= [(- b - sqrt (b ^ 2 - 4 * a * c)) / (2 * a),
(- b + sqrt (b ^ 2 - 4 * a * c)) / (2 * a)]
| nRoots == 1 = [- b / (2 * a)]
| otherwise = []
raizes.hs:8:23:
No instance for (Num (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from the literal ‘2’
In the second argument of ‘(==)’, namely ‘2’
In the expression: nRoots == 2
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
知道发生了什么事吗??
提前致谢
编辑:感谢您的所有回答!我现在因为没有注意到它而感到很愚蠢:X
您没有向 nRoots
传递任何参数。您可以通过将系数传递给 nRoots
来修复错误
roots a b c | nRoots a b c ==2 = ...
错误消息告诉您无法检查类型 Float -> Float -> Float -> Int
之类的东西(Eq
实例)是否相等,也没有办法将数字 2
转换为相同类型的数字(无 Num
实例)。这两个错误都是由表达式 nRoots == 2
.
引起的
您没有将您的函数 nRoot
应用于第二个函数中 guards 的参数。将函数 nRoots
应用于参数 a
、b
和 c
,然后您将能够比较它的结果。
您需要向 nRoots
提供适当的参数,特别是 roots a b c | nRoots a b c == 2 = ...
。
虽然您的错误消息告诉您这一点,但让我们来看看您应该如何阅读来自 GHC 的此错误消息以找出您的问题所在。我在下面用几个部分标记标记了错误消息。
raizes.hs:8:21:
---------------------BEGIN SECTION A--------------------
No instance for (Eq (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from a use of ‘==’
In the expression: nRoots == 2
---------------------END SECTION A--------------------
---------------------BEGIN SECTION B--------------------
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
In an equation for ‘roots’:
roots a b c
| nRoots == 2
= [(- b - sqrt (b ^ 2 - 4 * a * c)) / (2 * a),
(- b + sqrt (b ^ 2 - 4 * a * c)) / (2 * a)]
| nRoots == 1 = [- b / (2 * a)]
| otherwise = []
---------------------END SECTION B--------------------
raizes.hs:8:23:
---------------------BEGIN SECTION C--------------------
No instance for (Num (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from the literal ‘2’
In the second argument of ‘(==)’, namely ‘2’
In the expression: nRoots == 2
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
---------------------END SECTION C--------------------
首先让我们回顾一下==
的类型。
(==) :: Eq a => a -> a -> Bool
SECTION A
告诉您 ==
需要相等类型 class (Eq
) 的实例才能工作,因为它已过载以适用于任何类型一个 Eq
实例。不幸的是,nRoots
没有(并且可能没有非平凡的)Eq
实例,因为 nRoots
本身是一个函数(想想暂停问题)。 GHC 在这里给出的提示正是您的问题,即 GHC 注意到您正在尝试比较函数的相等性(在这种情况下为数字)并建议 maybe you haven't applied enough arguments to a function?
好的,就在 SECTION A
之后,我们似乎已经知道您面临的问题,但我们不要操之过急,也许 SECTION B
和 SECTION C
会表明您在 SECTION A
中看到的错误只是由更深层次的原因引起的表面错误。
好吧 SECTION B
实际上只是告诉您问题在 SECTION A
中的确切位置,所以这不是什么新鲜事。
那SECTION C
呢?还记得 ==
的类型吗?事实证明 ==
期望等式的两边是同一类型。所以现在 GHC 看到 nRoots == 2
并期望 nRoots
和 2
是同一类型。 Haskell 中的数字文字被重载为 Num a => a
类型,以便它们可以同时表示 Int
s、Integer
s、Double
s、Rational
s 等。所以现在 GHC 期望 nRoots
是 Num a => a
类型,其中 a
特别必须是 Float -> Float -> Float -> Int
,即它期望 nRoots
是Num
类型的实例 class.
正如 GHC 敏锐地暗示的那样,这实际上只是同一问题的另一种症状!也就是说,您忘记实际将参数应用于 nRoots
,因此 GHC 试图处理一个裸函数而不是函数的输出。
所以 Section A
和 Section C
都告诉你你有同样的问题,即当你应该完全应用你的函数时,你正在尝试使用函数本身 nRoots
该函数的参数并使用该函数的输出。
我在大学里使用 Haskell,我必须做的其中一项练习是创建一个函数,当我给出二次方程的系数时,它会给出二次方程的根,使用之前的函数告诉我有多少解决方案。这是我所做的:
第一个函数,这个很好用:
nRoots :: Float -> Float -> Float -> Int
nRoots a b c | r<0 = 0
| r==0 = 1
| otherwise = 2
where r = b^2-4*a*c
第二个功能,它不起作用:
roots :: Float -> Float -> Float -> [Float]
roots a b c | nRoots==2 = [(-b-sqrt(b^2-4*a*c))/(2*a),(-b+sqrt(b^2-4*a*c))/(2*a)]
| nRoots==1 = [-b/(2*a)]
| otherwise = []
这是我得到的错误:
raizes.hs:8:21:
No instance for (Eq (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from a use of ‘==’
In the expression: nRoots == 2
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
In an equation for ‘roots’:
roots a b c
| nRoots == 2
= [(- b - sqrt (b ^ 2 - 4 * a * c)) / (2 * a),
(- b + sqrt (b ^ 2 - 4 * a * c)) / (2 * a)]
| nRoots == 1 = [- b / (2 * a)]
| otherwise = []
raizes.hs:8:23:
No instance for (Num (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from the literal ‘2’
In the second argument of ‘(==)’, namely ‘2’
In the expression: nRoots == 2
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
知道发生了什么事吗??
提前致谢
编辑:感谢您的所有回答!我现在因为没有注意到它而感到很愚蠢:X
您没有向 nRoots
传递任何参数。您可以通过将系数传递给 nRoots
roots a b c | nRoots a b c ==2 = ...
错误消息告诉您无法检查类型 Float -> Float -> Float -> Int
之类的东西(Eq
实例)是否相等,也没有办法将数字 2
转换为相同类型的数字(无 Num
实例)。这两个错误都是由表达式 nRoots == 2
.
您没有将您的函数 nRoot
应用于第二个函数中 guards 的参数。将函数 nRoots
应用于参数 a
、b
和 c
,然后您将能够比较它的结果。
您需要向 nRoots
提供适当的参数,特别是 roots a b c | nRoots a b c == 2 = ...
。
虽然您的错误消息告诉您这一点,但让我们来看看您应该如何阅读来自 GHC 的此错误消息以找出您的问题所在。我在下面用几个部分标记标记了错误消息。
raizes.hs:8:21:
---------------------BEGIN SECTION A--------------------
No instance for (Eq (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from a use of ‘==’
In the expression: nRoots == 2
---------------------END SECTION A--------------------
---------------------BEGIN SECTION B--------------------
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
In an equation for ‘roots’:
roots a b c
| nRoots == 2
= [(- b - sqrt (b ^ 2 - 4 * a * c)) / (2 * a),
(- b + sqrt (b ^ 2 - 4 * a * c)) / (2 * a)]
| nRoots == 1 = [- b / (2 * a)]
| otherwise = []
---------------------END SECTION B--------------------
raizes.hs:8:23:
---------------------BEGIN SECTION C--------------------
No instance for (Num (Float -> Float -> Float -> Int))
(maybe you haven't applied enough arguments to a function?)
arising from the literal ‘2’
In the second argument of ‘(==)’, namely ‘2’
In the expression: nRoots == 2
In a stmt of a pattern guard for
an equation for ‘roots’:
nRoots == 2
---------------------END SECTION C--------------------
首先让我们回顾一下==
的类型。
(==) :: Eq a => a -> a -> Bool
SECTION A
告诉您 ==
需要相等类型 class (Eq
) 的实例才能工作,因为它已过载以适用于任何类型一个 Eq
实例。不幸的是,nRoots
没有(并且可能没有非平凡的)Eq
实例,因为 nRoots
本身是一个函数(想想暂停问题)。 GHC 在这里给出的提示正是您的问题,即 GHC 注意到您正在尝试比较函数的相等性(在这种情况下为数字)并建议 maybe you haven't applied enough arguments to a function?
好的,就在 SECTION A
之后,我们似乎已经知道您面临的问题,但我们不要操之过急,也许 SECTION B
和 SECTION C
会表明您在 SECTION A
中看到的错误只是由更深层次的原因引起的表面错误。
好吧 SECTION B
实际上只是告诉您问题在 SECTION A
中的确切位置,所以这不是什么新鲜事。
那SECTION C
呢?还记得 ==
的类型吗?事实证明 ==
期望等式的两边是同一类型。所以现在 GHC 看到 nRoots == 2
并期望 nRoots
和 2
是同一类型。 Haskell 中的数字文字被重载为 Num a => a
类型,以便它们可以同时表示 Int
s、Integer
s、Double
s、Rational
s 等。所以现在 GHC 期望 nRoots
是 Num a => a
类型,其中 a
特别必须是 Float -> Float -> Float -> Int
,即它期望 nRoots
是Num
类型的实例 class.
正如 GHC 敏锐地暗示的那样,这实际上只是同一问题的另一种症状!也就是说,您忘记实际将参数应用于 nRoots
,因此 GHC 试图处理一个裸函数而不是函数的输出。
所以 Section A
和 Section C
都告诉你你有同样的问题,即当你应该完全应用你的函数时,你正在尝试使用函数本身 nRoots
该函数的参数并使用该函数的输出。