4

我正在尝试实现余弦函数,这是我的代码:

cosC :: [a] -> a
cosC sides
   | length sides < 3          = 0
   | otherwise                 = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
   where x = head(tail(tail(sides)))
         y = head(tail(sides))
         z = head(sides)

但我得到两个错误:

No instance for (Fractional a)
arising from a use of `/'
In the expression: (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
In an equation for `cosC':
    cosC sides
      | length sides < 3 = 0
      | otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
      where
          x = head (tail (tail (sides)))
          y = head (tail (sides))
          z = head (sides)

No instance for (Num a)
arising from the literal `2'
In the first argument of `(*)', namely `2'
In the first argument of `(*)', namely `2 * x'
In the second argument of `(/)', namely `(2 * x * y)'

编辑:我已经修复了上面余弦定律中的符号错字。感谢 Daniel Fischer 指出这一点。

4

2 回答 2

11

您正在尝试从一般类型 a中计算数值结果,这可能行不通。(这就像试图为一般的公路车辆建造一座桥,也为一般的东西建造一座桥,例如宇宙飞船、摩天大楼、回形针和中子星)。只需将Floating约束添加到:

cosC :: Floating a => [a] -> a

您可以执行此类计算所需的任何算术运算。(Fractional对于这个函数实际上已经足够了,但是你将无法计算arccos结果)。


与您的问题无关,请注意在 Haskell 中分解列表有更好的方法:

cosC (x:y:z:_) = (x^2 + y^2 - z^2) / (2*x*y)
cosC _ = 0

相当于你的定义。你为什么要把这些论点当作一个清单呢?在 Haskell 中,我更喜欢用 Lisp 做的事情

cosC :: Floating a => a -> a -> a -> a
cosC x y z = (x^2 + y^2 - z^2) / (2*x*y)
于 2012-11-30T13:20:31.717 回答
5

cosC :: Fractional a => [a] -> a

这就是你可以找到的方法(in ghci):

*Main> let fun [x, y, z] = (x * x + y * y + z * z) / (2 * x * y)
*Main> :type fun
fun :: Fractional a => [a] -> a
于 2012-11-30T13:20:17.537 回答