不允许使用 Guard 中的函数。需要替代实施的建议
我正在尝试使用 fermats 方法 创建素数分解器。
此行生成错误
find_factors(A, B, FactorThis) when is_a_square(B) == true ->
对本地/导入函数 is_a_square/1 的调用在防护中是非法的
我看到此实现的唯一可能的替代方案是在函数中使用某种 case 语句。我正在避免这样做,因为它可能会搞砸尾递归。我是一个 Erlang 菜鸟。 还有哪些其他方法可以实现此功能?
get_int_part_of_sqrt(N) ->
trunc(math:sqrt(N)).
is_a_square(N) ->
get_int_part_of_sqrt(N) * get_int_part_of_sqrt(N) == N.
calculate_new_b(A, FactorThis) ->
NewB = trunc(abs((A * A) - FactorThis)),
io:format("Calculate_new_b A^2 ~w- FT ~w= NB ~w ~n",[A*A,FactorThis,NewB]),
find_factors(A, B, FactorThis) when is_a_square(B) == true ->
io:format("find_factors true ~w ~w~n", [A, B]),
{ok, A + get_int_part_of_sqrt(B), A - get_int_part_of_sqrt(B)};
find_factors(A, B, FactorThis) ->
io:format("find_factors false ~w ~w~n", [A, B]),
NewA = A + 1,
NewB = calculate_new_b(NewA, FactorThis),
find_factors(NewA, NewB, FactorThis).
已编辑。 修复了对calculate_new_b调用中的参数
添加了缺少的get_int_part_of_sqrts。
I am attempting to create a prime number factorizer, using fermats method.
This line generates an error
find_factors(A, B, FactorThis) when is_a_square(B) == true ->
call to local/imported function is_a_square/1 is illegal in guard
The only possible alternative I see to this implementation is to use some sort of case statement within the function. I was avoiding that, as it might screw up the tail recursion. I am a Erlang noob. What other ways are there to implement this functionality?
get_int_part_of_sqrt(N) ->
trunc(math:sqrt(N)).
is_a_square(N) ->
get_int_part_of_sqrt(N) * get_int_part_of_sqrt(N) == N.
calculate_new_b(A, FactorThis) ->
NewB = trunc(abs((A * A) - FactorThis)),
io:format("Calculate_new_b A^2 ~w- FT ~w= NB ~w ~n",[A*A,FactorThis,NewB]),
find_factors(A, B, FactorThis) when is_a_square(B) == true ->
io:format("find_factors true ~w ~w~n", [A, B]),
{ok, A + get_int_part_of_sqrt(B), A - get_int_part_of_sqrt(B)};
find_factors(A, B, FactorThis) ->
io:format("find_factors false ~w ~w~n", [A, B]),
NewA = A + 1,
NewB = calculate_new_b(NewA, FactorThis),
find_factors(NewA, NewB, FactorThis).
Edited.
fixed argument in call to calculate_new_b
added missing get_int_part_of_sqrts.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Erlang 故意限制你可以调用守卫的函数。 这是最近关于这样做的理由及其优点的讨论和缺点。
解决这个问题的唯一方法是使用
case
。您可以很容易地重写此代码以使用case
:请注意,上面的代码仍然是正确的尾递归。
(我对你的代码进行了一些修改,以删除我猜你不应该存在的部分)
Erlang deliberately restricts which functions you're allowed to call in guards. Here's a fairly recent discussion of the justification for this, its merits and drawbacks.
The only way around it is to use
case
. You can pretty easily rewrite this code to usecase
:Note that the above code is still properly tail-recursive.
(I modified your code a little to take out the parts that I'm guessing you meant not to have there)
这是围绕该问题进行重构的另一种方法。
添加所需的保护函数作为调用者的参数。这将其从可能有副作用的函数变为没有副作用的 true 或 false。然后直接模式匹配就可以完成这项工作。
Here is another way to refactor around the issue.
Add the desired guard function as an argument at the caller. This turns it from a function with possible side effects, into true or false, which have no side effects. Then straight pattern matching will do the job.