问题在于:声明类型并定义一个函数,它将2个正数(比如m和n)作为输入,并将m增加到n的幂。请仅使用递归。不要使用幂运算符或库函数,只需使用递归。
到目前为止,这是我的代码:
sqr :: Int - > Int - > INT
sqr m n
| m > 0 && n > 0 = sqr (m * m) (n - 1) | otherwise = m
出于某种原因,当我做sqr 10 2时,它给了我1000或者其他东西。有谁知道我做错了什么?
答案 0 :(得分:5)
让我们扩大。此外,您的功能应该被称为pow
,而不是sqr
,但这并不重要。
sqr 10 2 = sqr (10 * 10) (2 - 1)
= sqr 100 1
= sqr (100 * 100) (1 - 1)
= sqr 10000 0
= 10000
这说明了为什么sqr 10 2 = 10000
。
每次递增时,m
都有不同的值。所以你需要以某种方式考虑到这一点:
要么编写一个有效的版本,即使m
每次都有不同的值,或者
您可以找到一种方法来保持m
的原始价值。
我想说最简单的方法是使用m^n = m * m^(n-1)
和m^0 = 1
的事实。
如果你很聪明,有一种方法要快得多,这也取决于m^2n = (m^n)^2
的事实。
我上面写的一些数学公式实际上是有效的Haskell代码。
import Prelude hiding ((^))
infixr 8 ^
(^) :: Int -> Int -> Int
-- Do these two lines look familiar?
m^0 = 1
m^n = m * m^(n-1)
这只是该函数的中缀版本。您可以将中缀运算符更改为正常函数
pow :: Int -> Int -> Int
pow m 0 = 1
pow m n = m * pow m (n - 1)
更快的版本:
pow :: Int -> Int -> Int
pow m 0 = 1
pow m n
| even n = x * x where x = pow m (n `quot` 2)
| otherwise = m * pow m (n - 1)
答案 1 :(得分:4)
这里有两个不同的问题。只需写出所有术语重写步骤,看看它们是什么:
sqr 10 2
sqr (10 * 10) (2 - 1)
sqr 100 (2 - 1)
sqr 100 1
sqr (100 * 100) (1 - 1)
sqr 10000 (1 - 1)
sqr 10000 0
10000
这将清楚地向您展示其中一个问题。如果您还没有看到另一个,请尝试从
开始sqr 10 3