Function 哈斯克尔幂函数
如何编写一个利用以下事实的幂函数:要将x提升到幂n(其中n是一个正整数),如果n是偶数,你可以通过将该幂的一半平方得到x的n次幂。例如,x^12是x^6*x^6。对于奇数幂,只需从幂中减去一,然后将较小幂的结果乘以x。例如,x^13是x*x^12,这是x*x^6*x^6。递归地,任何幂都可以用比x本身乘以所示次数更少的功找到。 我想到了这个Function 哈斯克尔幂函数,function,haskell,overloading,Function,Haskell,Overloading,如何编写一个利用以下事实的幂函数:要将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 /
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)=>整数
*表达式:power 2 2查看
偶数的类型,并将其与/
的类型进行比较。首先,看一下偶数的类型签名:偶数::(积分a)=>a->Bool
odd
具有类似的签名。所以您可以看到,偶数
和奇数
取任何类型的整型
类型类并对其求值。然后查看/
:(/)::(分数a)=>a->a->a的签名<代码>/
只接受分数型
类型,不接受整数型
类型。一种类型不可能同时由这两个函数计算。在这种情况下,有一个简单的解决方法:使用div
而不是/
。请注意,如果使用div
作为中缀函数(将其放在参数之间),则需要在div
周围加上反勾号,现在代码正在运行:Haskell不会自动记忆函数,因此在最后两行中计算对power
的递归调用两次。我建议引入一个简单的函数并使用它。有几种方法:一个单独的功能;a其中
条款;和让
我更喜欢让:
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
正如您所看到的,模式匹配处理前两种情况。然后,让
定义一些有用的表达式,这些表达式可以稍后在
中的中使用。请注意,对于奇数,(n-1)`div`2
给出的结果与n`div`2
相同,因此我们可以统一这两种情况。我认为,计算幂的最快方法是:
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!)。看起来您使用的是拥抱。您可能想升级到GHC,以获得更好的Haskell体验。@不要,这可能是为了上课,在这种情况下,拥抱可能是强制性的。上周刚开始Haskell,我不明白为什么它不起作用嗯,就像5^10=25^5一样。所以你需要加幂的偶数部分(x*x,n/2)偶数是布尔的,如果它为真,那么函数返回我在它上面定义的,我不确定通过比较我得到了你的意思those@biz函数的类型包括其参数的类型,而不仅仅是它返回的类型。他们的参数类型是什么?ohh ok n是一个正整数我做了这个“|偶数n=(幂x(n(div)2))*(幂x(n(div)2))”错误文件:。\assign11.hs:2-函数绑定中的类型错误***项:幂***类型:a->((c->c->c)->d->b)->a***不匹配:a->b->a***,因为:统一将产生无穷大的type@biz我不太了解Hugs错误消息,但我相信这意味着函数的类型签名和它实际返回的类型不匹配。也许你忘了背勾了?例如,程序的第四行应该是这样的:|偶数n=(幂x(n'div'2))*(幂x(n'div'2))
。不要复制和粘贴该代码,因为由于stackoverflow的标记语法,我使用了撇号而不是反勾号。该行中的每一个撇号都应该替换为一个反勾号(`),它可能位于键盘上的tab键上方。@biz Great!如果您再次遇到这样的问题,您可以使用查找函数的类型签名,或者如果您得到GHC和,则使用GHCI查找函数的类型签名,这是强烈建议的。