本博客所有内容是原创,未经书面许可,严禁任何形式的转载。
http://blog.csdn.net/u010255642
14、递归
在haskell中没有for、loop、while之类的语句,而是采用递归来替代循环。递归函数是指一些会在函数内调用自己的函数,我们写一个求列表中最小数的函数
mymin::(Ord a)=>[a]->a
mymin []=error "empty list!"
mymin [x]=x
mymin (x:xs)
|x<minval=x
|otherwise=minval
where minval=mymin xs
运行一下
*Main> mymin [12,22,8]
8
*Main> mymin [12,22,88]
12
*Main> mymin [52,22,88]
22
我们以[52,22,88]为例说明递归的过程, mymin函数匹配(x:xs),先提取52为x的值,然后执行where语句的minval=mymin xs ,此时,xs为[22,88],再一次调用 mymin,函数再次匹配(x:xs),执行where语句后,xs为[88],函数匹配mymin [x]=x,mymin首次返回了需要的值88,即minval为88,此时递归到了底层,不会再继续调用mymi,开始回溯,读取到了x为22,minval为88,最终求得最小值为22
下面这个完成对一个列表的偶校验。
-------
myct::[Int]->Int
myct []=0
myct (x:xs)=x+mysum
where mysum=myct xs
myecc mydata=mydata ++ [(myct mydata) `mod` 2]
运行效果为:
*Main> myecc [1,0,0,1,1]
[1,0,0,1,1,1]
*Main> myecc [1,0,0,1,0]
[1,0,0,1,0,0]
*Main>
递归存在效率低下和占用堆栈耗用量的问题,我们来体验下尾递归, 如果在递归函数中,递归调用返回的结果总被直接返回,则称为尾部递归。
下面是一个阶乘的尾递归:
mycproduct::Int->Int->Int
mycproduct myn mya
|myn<0=0
|myn==0=1
|myn==1=mya
|otherwise=mycproduct (myn-1) (myn*mya)
运行效果如下:
*Main> mycproduct 5 1
120
*Main> mycproduct 2 1
2
*Main> mycproduct 3 1
6
*Main> mycproduct 4 1
24
*Main> mycproduct 5 1
120