【问题标题】:Haskell Quadratic solution finder - ErrorHaskell 二次解法查找器 - 错误
【发布时间】:2019-10-07 11:17:49
【问题描述】:

我在大学里使用 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

【问题讨论】:

    标签: haskell quadratic


    【解决方案1】:

    您没有向nRoots 传递任何参数。您可以通过将系数传递给nRoots来修复错误

    roots a b c | nRoots a b c ==2 = ...
    

    错误消息告诉您,无法检查 nRoots 之类的是否相等(Eq 实例),其类型为 Float -&gt; Float -&gt; Float -&gt; Int,并且无法将数字 2 转换为具有相同类型的数字(没有Num 实例)。这两个错误都是由表达式 nRoots == 2 引起的。

    【讨论】:

      【解决方案2】:

      您需要为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 告诉您 == 需要相等类型类 (Eq) 的实例才能工作,因为它已重载以适用于具有 Eq 实例的任何类型。不幸的是,Eq 没有(也可能没有非平凡的)实例 nRoots 因为 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 =&gt; a 类型,因此它们可以同时表示 Ints、Integers、Doubles、Rationals 等。所以现在 GHC 期望 nRoots属于Num a =&gt; a 类型,其中a 尤其必须是Float -&gt; Float -&gt; Float -&gt; Int,即它期望nRoots 是Num 类型类的一个实例。

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

      所以Section A 和Section C 都在告诉你你有同样的问题,即你试图使用一个函数本身nRoots 当你应该将你的参数完全应用到该函数并使用该函数的输出。

      【讨论】:

        【解决方案3】:

        您没有将您的函数 nRoot 应用于第二个函数的守卫中的参数。将你的函数nRoots 应用到参数a、b 和c,然后你就可以比较它的结果了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-01-29
          • 1970-01-01
          • 2013-03-21
          • 1970-01-01
          • 2023-04-06
          • 2014-03-01
          • 1970-01-01
          相关资源
          最近更新 更多