包含标签 FP 的文章

python 迭代器和惰性计算、函数式编程基础

​ 本文介绍了python 的生成器,构造一些有趣的惰性计算程序,可以作为python函数式的基础。 1. iterator and generator ​ 众所周知,python3里面的range返回是一个对象而不是列表,它的前身是python 2的xrange。python 2里面的range会生成一个列表,当这个列表很大时,会有严重的性能问题: for x in range(0,100000): print(x) ​ 可以使用iter(range(0,100000))将range对象转换为可迭代实例(iterator),下面的代码是和上面代码等价的: lst=iter(range(0,10)) while True: try: b = next(lst) # 调用lst.__next__() print(b) except StopIteration: break ​ 显而易见,其实python的for循环其实是个语法糖,首先隐式将list(可迭代对象)转换为list_iterator,然后不断调用迭代器的__next__函数,直到出现StopIteration为止;下面是一个迭代器的实例(注意内部函数__next__): class fibonacci: '''To use this class like this for n in fibonacci(100): print(n, end=',') ''' def __init__(self, max): self.max = max #可迭代对象实现了__iter__方法,str、list、set、dict、file、sockets等容器都有这个内部函数 def __iter__(self): self.……

阅读全文

fold and unfold

​ Haskell里面有两个著名的fold函数:foldr/foldl,这两个函数非常具有函数式编程的特点(递归),几户所有的Haskell教程都会使用foldr/foldl来完成一些命令式语言的循环语句。还有个更少见的unfoldr函数,可以完成一些匪夷所思的操作。 1 fold ​ 几乎所有的函数式语言都有类似的函数,如Javascript的对应是reduce1reduceRight();Haskell的fold有两个版本,分别是foldr和foldl,两个函数主要区别在后缀上,一个从右折叠,一个从左折叠,位于Data.List,常见的教程里面定义的简单版本如下: foldr :: (a -> b -> b) -> b -> [a] -> b foldr step zero (x:xs) = step x (foldr step zero xs) foldr _ zero [] = zero foldl :: (a -> b -> a) -> a -> [b] -> a foldl step zero (x:xs) = foldl step (step zero x) xs foldl _ zero [] = zero ​ fold的参数依次为step函数、初始值、列表,返回值为一个和初始值类型一样的值。注意foldr和foldl的step函数都是二元函数,foldr的step参数顺序为列表元素、折叠变量,foldl的刚好反过来!这点很容易搞混淆。一般我们直接使用预定义的就行,当然对于Data.Tree等可折叠的类型,foldr/foldl也可以适用,方法类似。 ​ 众所周知,Haskell构造列表只能向头部插入元素:1:[2,3],连接链表也可以使用concat函数或者++:[1.……

阅读全文