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 应用于参数 abc,然后您将能够比较它的结果。

您需要向 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 BSECTION C 会表明您在 SECTION A 中看到的错误只是由更深层次的原因引起的表面错误。

好吧 SECTION B 实际上只是告诉您问题在 SECTION A 中的确切位置,所以这不是什么新鲜事。

SECTION C呢?还记得 == 的类型吗?事实证明 == 期望等式的两边是同一类型。所以现在 GHC 看到 nRoots == 2 并期望 nRoots2 是同一类型。 Haskell 中的数字文字被重载为 Num a => a 类型,以便它们可以同时表示 Ints、Integers、Doubles、Rationals 等。所以现在 GHC 期望 nRootsNum a => a 类型,其中 a 特别必须是 Float -> Float -> Float -> Int,即它期望 nRootsNum 类型的实例 class.

正如 GHC 敏锐地暗示的那样,这实际上只是同一问题的另一种症状!也就是说,您忘记实际将参数应用于 nRoots,因此 GHC 试图处理一个裸函数而不是函数的输出。

所以 Section ASection C 都告诉你你有同样的问题,即当你应该完全应用你的函数时,你正在尝试使用函数本身 nRoots该函数的参数并使用该函数的输出。