我希望遍历一个NxN区域,给定起点X,Y和要遍历的正方形的大小。例如。给定X = 10,Y = 12,大小= 2 - 我想生成10,10; 10,11; 11,10和11,11。
我想出了这个,但它似乎无限地继续下去:
traverse({X,Y,Xend,Yend}) ->
% print X,Y values here....
case (X == Xend-1) andalso (Y == Yend-1) of
true ->
ok;
_->
case (Y < Yend-1) of
true ->
traverse({X,Y+1,Xend,Yend});
_->
traverse({X+1,Y,Xend,Yend})
end
end.
我用另一个函数调用了上面的函数:
Size = 3,
traverse({10,20,10+Size,20+Size}).
我做错了什么?我实际上是功能范例的新手,我尝试在C上实现这个,使用“返回”代替上面的“确定”,它有效,但我猜,我不是在考虑“功能”! / p>
答案 0 :(得分:3)
traverse(X0, Y0, S) ->
[
io:format("coords: ~p~n", [{X,Y}])
|| X <- lists:seq(X0, X0 + S - 1),
Y <- lists:seq(Y0, Y0 + S - 1)
],
ok
shell中的:
1> traverse(10, 12, 2).
coords: {10,12}
coords: {10,13}
coords: {11,12}
coords: {11,13}
ok
答案 1 :(得分:2)
试试这个:
traverse({X,Y,Xend,Yend}) ->
dotraverse(X, Y, Xend, Yend, _StartX=X).
dotraverse({Xend,Yend,Xend,Yend}, SX) ->
ok;
dotraverse({X,Y,Xend,Yend}, SX) when X<Xend ->
%print
dotraverse({X+1, Y, Xend, Yend}, SX);
dotraverse({Xend,Y,Xend,Yend}) ->
dotraverse(SX,Y+1, Xend, Yend}, SX).
注意:未经测试但你得到了它的要点。
答案 2 :(得分:2)
这是一个很好的问题,来自功能范例的新手。这里更大的错误是代码被思考的方式,而不是它不起作用的事实。
由于你来自C,你很自然地以强制性的方式编写代码,因为这就是你的思考方式。
在函数式样式中,你必须告诉编译器你要做什么,而不是像在C等命令式语言中那样“怎么做”.Zed给出的示例使用列表理解是正确的方法
编写代码是学习的最佳方式,但请确保您也专注于以功能性方式进行思考。需要一段时间才能实现飞跃,但不断编写代码,最终会实现目标。
如果您认真对待Erlang,请阅读Joe Armstrong的书或Cesarini和Thompson的书,或阅读erlang.org的“OTP设计原则用户指南”。这些将帮助您开始以不同的方式思考,花费的时间将非常值得。