Erlang:N区域穿越N.

时间:2009-12-09 16:35:44

标签: functional-programming erlang

我希望遍历一个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>

3 个答案:

答案 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设计原则用户指南”。这些将帮助您开始以不同的方式思考,花费的时间将非常值得。