Haskell 幂函数
如何编写利用以下事实的幂函数: 要将 x 计算到 n 次方(其中 n 是正整数),如果 n 是偶数,则可以通过对该次方的一半进行平方来找到 x 的 n 次方。例如,x^12 是 x^6 * x^6。对于奇数幂,只需从幂中减一,然后将较小幂的结果乘以 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
how to write a power function which makes use of the following facts: To raise x to a power n (where n is a positive whole number), if n is even, you can find the nth power of x by squaring half that power. For example, x^12 is x^6 * x^6. For odd powers, just subtract one from the power, and multiply the result for the smaller power by x. for example, x^13 is x * x^12, which is x * x^6 * x^6. Recursively, any power can be found with less work than multiplying x by itself the number of times indicated.
I came up with this
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) )
but I get an error saying ERROR - Unresolved overloading
* Type : (Integral a, Fractional a) => Integer
* Expression : power 2 2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里发生的是一种常见的类型不匹配。首先,看一下
even
的类型签名:even :: (Integral a) =>一个->布尔。
odd
有类似的签名。因此您可以看到,even
和odd
采用Integral
类型类的任何类型并对其进行求值。然后查看/
的签名:(/) :: (Fractional a) =>一个->一个->一个。
/
仅采用Fractional
类型,而不采用Integral
类型。一种类型不可能同时被这两个函数求值。在这种情况下,有一个简单的解决方法:使用div
而不是/
。请注意,如果您使用div
作为中缀函数(将其放置在参数之间),则需要在div
周围添加反引号。What's happened here is a common type mismatch. First, take a look at the type signature for
even
:even :: (Integral a) => a -> Bool
.odd
has a similar signature. So you can see thateven
andodd
take any type of theIntegral
typeclass and evaluate it. Then look at the signature for/
:(/) :: (Fractional a) => a -> a -> a
./
takes onlyFractional
types, notIntegral
ones. It's impossible for one type to be evaluated by both those functions. In this case, there's an easy fix: usediv
instead of/
. Note that if you usediv
as an infix function (place it between the arguments) you'll need to put backticks arounddiv
.查看
even
的类型并将其与/
的类型进行比较。Look at the type of
even
and compare that to the type of/
.现在您的代码正在运行,请注意:Haskell 不会自动记忆函数,因此您在最后两行中计算了两次对
power
的递归调用。我建议引入一个简单的函数sqr k = k * k
并使用它。有几种方式:单独的函数;一个where
子句;并让
。我更喜欢
let
:正如您所看到的,模式匹配处理前两种情况。然后
let
定义了一些有用的表达式,稍后可以在in
中使用。请注意,对于奇数,(n-1) `div` 2
给出的结果与n `div` 2
相同,因此我们可以统一这两种情况。Just a remark now that your code is running: Haskell doesn't automatically memoize functions, so you're calculating the recursive calls to
power
twice in the last two lines. I would recommend to introduce a simple functionsqr k = k * k
and to use it. There are several ways: a separate function; awhere
clause; andlet
.I would prefer
let
:As you can see pattern matching deals with the first two cases. Then
let
defines some useful expressions, which can be used later inin
. Note that for odd numbers,(n-1) `div` 2
gives the same result asn `div` 2
, so we can unify both cases.我认为,计算幂的最快方法:
您也可以使用“Int”代替“Integer”(将签名中的Int上的Integer替换为Integer!)。
I think, the fastest way to calculate power:
you can also use "Int" instead "Integer"(replace Integer on Int in the signature!).