妙不可言的函数编程。为什么这么说呢,当我看完第三章时,被erlang的编程方式深深的吸引住了,但是作者总是在我觉得很精妙的地方说:“该方法在实际编程中很少用到”T_T。python也有函数编程的思想,不过一直没有用到过,可能还停留在初级阶段。下面的笔记也只是自己学习中的所悟,可能有着大量的错误,如果你发现我理解的不对,感谢留言指正。请带着怀疑的态度看此笔记。
1、模块。
模块文件存放在扩展名为.erl的文件中,编译完成后的扩展名为.beam。
文件名geometry.erl(博客不支持erlang语法高亮,蛋疼了。。)
-module(geometry).
-export([area/1]).
area({rectangle,Width,Ht}) -> Width * Ht;
area({circle,R}) -> 3.14 * R * R
执行过程:先需要将erlang shell目录移动到代码目录下,查看当前目录命令pwd(),cd(Dir)。
2> c(geometry).
{ok,geometry}
6> geometry:area({rectangle,10,5}).
50
7> geometry:area({circle,1.4}).
6.1544
字句顺序不重要,但调用参数的匹配过程是从上向下的。函数不能处理模式匹配失败的情况,将会抛出一个运行时错误。
2、fun匿名函数
1> Z = fun(X) -> 2*X end.
#Fun<erl_eval.6.82930912>
2> Z(3).
6
这个简单的例子介绍fun函数的用法,用一个"end"做结尾。第三行语句的值为一个函数Z(X)=2*X
以fun为参数的函数
3> Even = fun(X) -> (X rem 2) =:= 0 end.
#Fun<erl_eval.6.82930912>
4> Even(8).
true
5> Even(3).
false
6> lists:map(Even,[1,2,3,4,5,6,7,8]).
[false,true,false,true,false,true,false,true]
7> lists:filter(Even,[1,2,3,4,5,6,7,8]).
[2,4,6,8]
第三个语句,我们定义了一个Even函数,用来求变量是否是偶数,是返回true。
第四第五语句是函数的使用。
第六行将函数Even作为参数,将列表中的每一个元素代入Even,得到的值生成一个新的列表。lists:filter是将满足使Even值为true的列表元素生成一个新列表。
返回fun的函数
11> Fruit = [apple,pear,orange].
[apple,pear,orange]
12> MakeTest = fun(L) -> (fun(X) -> lists:member(X,L)end) end.
#Fun<erl_eval.6.82930912>
13> IsFruit = MakeTest(Fruit).
#Fun<erl_eval.6.82930912>
14> IsFruit(pear).
true
15> IsFruit(dog).
false
17> BoxList = [dog,orange,cat,apple,bear].
[dog,orange,cat,apple,bear]
18> lists:filter(IsFruit,BoxList).
[orange,apple]
11行定义了一个Fruit列表,里面都是水果(⊙﹏⊙b汗)。十二行定义了一个函数MakeTest(L),他的值为一个fun函数,这个fun函数的功能是看变量X是否是L中的元素,是返回True。(感觉就是二元一次方程,你必须知道两个变量才能求得一个结果值)
第13行定义函数IsFruit(X)=lists:member(X,Fruit),当然我这样表示是不正确的,只是为了写得像数学上的函数。正确是IsFruit = fun(X) -> lists:member(X,Fruit) end,这样这个函数的功能变成:看X是否是水果,是返回true。
第14,15行进行了函数测试。十七行定义了一个篮子,里面各种东西,我们要挑出水果,用我们的lists标准库,如果IsFruit为true,那么是水果,则挑拣到另一个篮子里。哇哈哈~
定义自己的抽象流程控制:
这里更是可以举一反三,做你想做的^_^。
书上给了一个for循环控制结构的实现:(语法不支持高亮,就用截图了,不高亮我自己看着别扭)
[caption id="attachment_578" align="alignnone" width="300" caption="erlang编程"][/caption]
这是实现了for(i=0,i<10,i++),for i in range(0,10),简单的你可以实现一个for i in range(0,10,2)。
解释一下程序:如果第一个参数值与第二个相同,返回执行 F(Max),否则匹配第二个,F(I)作为列表的头,for(I+1,Max,F)作为列表尾。
如果看到这里,你也会有疑问,为什么不写第二条语句在第一条上面呢?因为交换以后,for(I,Max,F)将满足任何语句,就不会执行第二条语句。编译器也会提示给你:lib_misc.erl:6: Warning: this clause cannot match because a previous clause at line 5 always matches。你的执行将会死循环。当然如果你输入的匹配I>Max,也会进入死循环。
我感觉这将比其他语言的for循环更加灵活。
25> c(lib_misc).
{ok,lib_misc}
26> lib_misc:for(1,10,fun(I) -> I end).
[1,2,3,4,5,6,7,8,9,10]
27> lib_misc:for(1,10,fun(I) -> I*I end).
[1,4,9,16,25,36,49,64,81,100]
28>
编译,26行打印1-10整数列表,27行打印平方列表。
先整理这么多,第二章的笔记是边学边记,第三章是一口气给看完了。⊙﹏⊙b汗
上一篇: mysql图形化界面工具
下一篇: vim erlang插件配置
最近也在看这书。交换一下友链吧