如何编写一个利用以下事实的幂函数:将x提高到幂n(其中n是正整数),如果n是偶数,你可以通过平方半找到x的n次幂那力量。例如,x ^ 12是x ^ 6 * x ^ 6。对于奇数功率,只需从功率中减去1,然后将较小功率的结果乘以x。例如,x ^ 13是x * x ^ 12,其是x * x ^ 6 * x ^ 6。递归地,可以找到任何功率而不是将x乘以指示的次数。 我想出了这个
power x n
| n == 0 = 1
| x == 0 = 0
| even n = ( power x (n / 2) ) * ( power x (n / 2) )
| odd n = x * ( power x ((n - 1) / 2)) * ( power x ((n - 1) / 2) )
但是我收到错误说错误 - 未解决的重载 *类型:(积分a,分数a)=>整数 * 表达:力量2 2
答案 0 :(得分:4)
这里发生的是一种常见的类型不匹配。首先,请查看even
的类型签名:even :: (Integral a) => a -> Bool
。 odd
有类似的签名。因此,您可以看到even
和odd
采用任何类型的Integral
类型类并对其进行评估。然后查看/
:(/) :: (Fractional a) => a -> a -> a
的签名。 /
仅采用Fractional
种类型,而非Integral
类型。这两种函数都不可能评估一种类型。在这种情况下,有一个简单的解决方法:使用div
代替/
。请注意,如果您使用div
作为中缀函数(将其置于参数之间),则需要在div
周围添加反引号。
答案 1 :(得分:2)
查看even
的类型,并将其与/
的类型进行比较。
答案 2 :(得分:1)
现在您的代码正在运行:Haskell不会自动记忆函数,因此您在最后两行计算两次递归调用power
。我建议引入一个简单的函数sqr k = k * k
并使用它。有几种方法:一个单独的功能;一个where
条款;和let
。
我更希望let
:
power _ 0 = 1
power 0 _ = 0
power x n = let sqr k = k * k
half_n = n `div` 2
sqrHalfPower = sqr ( power x half_n )
in if even n then sqrHalfPower else x * sqrHalfPower
正如您所见,模式匹配处理前两种情况。然后let
定义了一些有用的表达式,可以在in
中使用。请注意,对于奇数,(n-1) `div` 2
给出与n `div` 2
相同的结果,因此我们可以统一这两种情况。
答案 3 :(得分:0)
我认为,计算能力的最快方法是:
pow:: Integer->Integer->Integer
pow x n |(n==1) = x
|even n = (pow x ( div n 2))*(pow x ( div n 2))
|odd n = x * (pow x (n-1))
您也可以使用“Int”代替“Integer”(在签名中替换Int上的Integer!)。