我的Google Reader分享

Monday, July 28, 2008

Programming Erlang 笔记(二)

Sequential Programming

Modules(模块)
  • Modules are the basic unit of code in Erlang.────模块是Erlang中基本的代码单元。
  • -module(geometry).
    -export([area/1]).
    area({rectangle, Width, Ht}) -> Width * Ht;
    area({circle, R}) -> 3.14159 * R * R.
    (这就是一个模块,geometry.erl)
  • 上面的例子中,函数area由两个子句组成,子句用分号隔开,最后用点号结束。
  • Each clause has a head and a body; the head consists of a function name followed by a pattern (in parentheses), and the body consists of a sequence of expressions, which are evaluated if the pattern in the head is successfully matched against the calling arguments. The patterns are matched in the order they appear in the function definition.────每个子句有一个头和身体;头由函数名跟着一个模式(在括号中)组成,身段由一序列的表达式组成,当头中的模式和调用的参数相匹配时,表达式就会被计算。模式按在函数中被定义的顺序进行匹配。
  • compile and run it:
    1> c(geometry).
    {ok,geometry}
    2> geometry:area({rectangle, 10, 5}).
    50
    3> geometry:area({circle, 1.4}).
    6.15752
  • the order of the clauses doesn’t matter, if the patterns in the clause are mutually exclusive.In general, though, clause order does matter.────如果子句中的模式是互斥的,那么子句就顺序就无所谓了。但是一般情况下,子句的顺序很有关系。


Functions with the Same Name and Different Arity
  • The arity of a function is the number of arguments that the function has. In Erlang, two functions with the same name and different arity in the same module represent entirely different functions. They have nothing to do with each other apart from a coincidental use of the same name.────一个函数的arity是指这个函数拥有的参数的个数。在Erlang中,同一个模块中名字相同但arity不同的两个函数是完全不同的两个函数。它们仅仅是巧合的有了相同的名字而已。
  • Here’s an example:
    sum(L) -> sum(L, 0).
    sum([], N) -> N;
    sum([H|T], N) -> sum(T, H+N).

Funs
  • funs are “anonymous” functions.────"funs"是匿名的函数。
  • 1> Z = fun(X) -> 2*X end.
    #Fun
    2> Z(2).
    4
    3> Double = Z.
    #Fun
    4> Double(2).
    4
    5> Hypot = fun(X, Y) -> math:sqrt(X*X + Y*Y) end.
    #Fun
    6> Hypot(3,4).
    5.00000
    7> Hypot(3).

    =ERROR REPORT==== 28-Jul-2008::20:14:30 ===
    Error in process <0.31.0> with exit value: {{badarity,{#Fun,[3]}},[{erl_eval,expr,3}]}

    ** exited: {{badarity,{#Fun,[3]}},[{erl_eval,expr,3}]} **
    8> TempConvert = fun({c, C}) -> {f, 32 + C*9/5};
    8> ({f, F}) -> {c, (F-32)*5/9}
    8> end.
    #Fun
    9> TempConvert({c,100}).
    {f,212.000}
    10> TempConvert({f, 212}).
    {c,100.000}
    11> TempConvert({c, 0}).
    {f,32.0000}
    12>
  • Functions that return funs, or functions that can accept funs as their arguments, are called higher-order functions.────那些返回funs,或者可以接受funs作为参数的函数叫作"higher-order"函数。
  • Functions That Have Funs As Their Arguments
    1. 12> L = [1,2,3,4].
      [1,2,3,4]
      13> lists:map(Double, L).
      [2,4,6,8]
      14> Even = fun(X) -> (X rem 2) =:= 0 end.
      #Fun
      15> Even(8).
      true
      16> Even(7).
      false
      17> lists:map(Even, [1,2,3,4,5,6,8]).
      [false,true,false,true,false,true,true]
      18> lists:filter(Even, [1,2,3,4,5,6,8]).
      [2,4,6,8]
      (接上例)
  • Functions That Return Funs
    1. 1> Fruit = [apple,pear,orange].
      [apple,pear,orange]
      2> MakeTest = fun(L) -> (fun(X) -> lists:member(X, L) end) end.
      #Fun
      3> IsFruit = MakeTest(Fruit).
      #Fun
      4> IsFruit(pear).
      true
      5> IsFruit(apple).
      true
      6> IsFruit(dog).
      false
      7> lists:filter(IsFruit, [dog,orange,cat,apple,bear]).
      [orange,apple]

the use of the -import and -export declarations in the module
  • The declaration -import(lists, [map/2, sum/1]). means the function map/2 is imported from the module lists, and so on. This means we can write map(Fun, ...) instead of lists:map(Fun, ...). cost/1 was not declared in an import declaration, so we had to use the “fully qualified” name shop:cost.────定义"-import(lists,[map/2,sum/1])"的意思是函数"map/2"是从模块"lists"中导入的。所谓导入的意思是指你可以用"map(Fun,...)这样的写法代替"lists:map(Fun, ...)"。而比如"cost/1"在导入声明中没有被声明,则我们必须使用"fully qualified"名称"shop:cost".
  • The declaration -export([total/1]) means the function total/1 can be called from outside the module shop2. Only functions that are exported from a module can be called from outside the module.────定义"-export([total/1])的意思是指函数"total/1"可以从模式外面被调用。只有那些从模块中导出的函数才可以在模块外被调用。


List Comprehensions
  • List comprehensions are expressions that create lists without having to use funs, maps, or filters. This makes our programs even shorter and easier to understand.────List comprehensions是一种可以不使用funs,maps,filters就可以创建lists(列表)的表达式。这让我们的程序更加短小,而且更加容易理解。
  • 1> L = [1,2,3,4,5].
    [1,2,3,4,5]
    2> lists:map(fun(X) -> 2*X end, L).
    [2,4,6,8,10]
    3> [2*X || X <- L]. [2,4,6,8,10]
  • The notation [ F(X) || X <- L] means “the list of F(X) where X is taken from the list L.” Thus, [2*X || X <- L ] means “the list of 2*X where X is taken from the list L.”────"[F(X) || X <- L]"的意思是指"经过F(X)处理的列表,X来自于列表L"。因而,"[2*X || X <- L]的意思是“经过2*X处理的的列表,X来自于列表L”。
  • 4> Buy=[{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}].
    [{oranges,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]
    5> [{Name, 2*Number} || {Name, Number} <- Buy].
    [{oranges,8},{newspaper,2},{apples,20},{pears,12},{milk,6}]

No comments: