Erlang 编程/列表推导
列表推导是一种数学方法,用于构造列表。要进行列表推导,我们必须使用一个新的运算符“<-”,“取自”。
L = [ X*X || X <- [1,2,3,4] ].
英文翻译是:构建一个列表 L,其元素的值为 X*X,条件是 X 取自列表 [1,2,3,4]。它输出
[1,4,9,16]
请注意,这类似于
lists:map(fun(X) -> X*X end, [1,2,3,4])
事实上,列表推导为 lists 模块中的大多数函数提供了一种简写表示法。
您可以使用它们来求解方程。
L = [ {X,Y} || X <- [1,2,3,4], Y <- [1,2,3,4], X*X == Y].
输出
[ {1,1}, {2,4} ]
你能弄清楚上面推导中使用的列表函数吗?
怎么样
F = fun(X, Y) -> lists:filter(fun({X0, Y0}) -> X0 * X0 == Y0 end, lists:reverse( lists:foldl(fun(E, Acc) -> lists:zip(lists:duplicate(length(Y), E), Y) ++ Acc end, [], X))) end. F([1,2,3,4], [1,2,3,4]).
那是 5 个函数在一个简洁的行中。对于剩余的示例,花一些时间找到执行相同操作的相应列表函数。
这里我们掷两枚硬币
[ [X]++[Y] || X<-"HT", Y<-"HT"].
注意:在 erlang 中,字符串是列表。所有组合是:输出
["HH","HT","TH","TT"]
列表推导的一个重要用途是帮助将 Prolog 式语句翻译成 Erlang。[为什么这很重要?]
1- Erlang 是一种面向函数的语言,专为消息传递(MIMD)并行处理而设计。Prolog 专为逻辑编程而设计。有时,问题最容易被定义为对某些数据集的一组逻辑约束。如果有人从逻辑上思考或从约束上思考,或者从 prolog 上思考,这种列表推导风格可以是你在 erlang 中完成任务的有效方法。在 prolog 中存在许多有用的解决方案,可以通过列表推导迁移到 erlang。
2- 约束编程和逻辑编程被认为是比函数更高级的编程方式,因此,它们是节省时间并提高简洁性的好方法。
警告:基于约束和逻辑的程序可能更难调试,因为严格的逐步操作被隐藏并委托给列表推导引擎。erlang 列表推导中约束的顺序会影响输出。约束的顺序依赖性可能是非直观的干扰。
注意:一般来说,使用大量原子并不是一个好主意,因为它们永远不会被垃圾回收。
-module(think). % -compile(export_all). % % male(adam) -> true; % male(seth) -> true; male(cain) -> true; male(abel) -> true; male(noah) -> true; male(_X) -> false. % female(eve) -> true; female(_X) -> false. % parent(adam,cain) -> true; parent(adam,abel) -> true; parent(eve,cain) -> true; parent(eve,abel) -> true; parent(noah,shem) -> true; parent(_X,_Y) -> false. % people() -> [ adam, shem, cain, abel, eve, noah ]. % father_of() -> [ {X,Y} || X <- people(), Y <- people(), parent(X,Y), male(X) ]. mother_of() -> [ {X,Y} || X <- people(), Y <- people(), parent(X,Y), female(X) ].
使用 c(think) 编译并使用以下命令生成输出
17> think:father_of() ++ think:mother_of(). [{adam,cain},{adam,abel},{noah,shem},{eve,cain},{eve,abel}]
带 7 行代码的快速排序示例。
-module(sort). -compile(export_all). % classic way to show off erlang terseness. qsort([]) -> []; qsort([H | T]) -> qsort([ X || X <- T, X < H ]) ++ [H] ++ qsort([ X || X <- T, X >= H ]).
% sample output: % % sort:qsort([1,5,3,7,6,8,9,4]). % [1,3,4,5,6,7,8,9]
(顺便说一句:这实际上不是“快速排序”,因为你想使用它,因为它使用比必要更多的内存,并且没有获得就地快速排序的 VM 页面/缓存优势。但它仍然很酷!)
1) 使用列表推导编写一个程序,找到半径为 5 的圆的整数解 {X,Y}。
1)
-module( solve_circle). -export( [start/0] ). % numbers() -> lists:seq(-5,5). % start() -> [ {X,Y} || X <- numbers(), Y <- numbers(), X*X + Y*Y == 25 ]. % % ================================================ % % sample output % 11> solve_circle:start(). % [{-5,0}, {-4,-3}, {-4,3}, {-3,-4}, % {-3,4}, {0,-5}, {0,5}, {3,-4}, % {3,4}, {4,-3}, {4,3}, {5,0}]