Erlang : Traversing N by N area
I am looking to traverse a NxN area, given the starting points X,Y and the size of the square to traverse. E.g. given X=10,Y=12,Size=2 - i want to generate 10,10 ; 10,11 ; 11,10 and 11,11.
I came up with this, but it seems to go on and on inf开发者_如何学编程initely:
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.
I called the above function from another function using:
Size = 3,
traverse({10,20,10+Size,20+Size}).
What am I doing wrong? I am actually new to the functional paradigm, and I tried implementing this on C, using "return" in the place of "ok" above, and it worked, but I am guessing, i'm not thinking "functionally" enough!
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
in shell:
1> traverse(10, 12, 2).
coords: {10,12}
coords: {10,13}
coords: {11,12}
coords: {11,13}
ok
Try this:
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).
Note: untested but you get the gist of it.
This is a good question coming from someone new to the functional paradigm. The larger mistake here is the way the code is thought out, not the fact that it doesn't work.
Since you are coming from C, it's natural that you're writing the code in an imperative style, because that's how you're thinking.
In the functional style you have to tell the compiler "what" you want to do, not "how to do it" like you do in imperative languages such as C. The example Zed gives using the list comprehension is the right way.
Writing code is the best way to learn, but make sure you also focus on thinking in a functional manner. It takes a while to make the leap, but keep writing code and you'll get there eventually.
If you're serious about Erlang, read either Joe Armstrong's book or that of Cesarini and Thompson, or read the "OTP Design Principles User's Guide" from erlang.org. These will help you start to think differently, and the time spent will be well worth it.
精彩评论