【问题标题】:How to invoke Erlang function with variable?如何使用变量调用 Erlang 函数?
【发布时间】:2015-06-22 07:19:52
【问题描述】:
4> abs(1).
1
5> X = abs.
abs
6> X(1).
** exception error: bad function abs
7> erlang:X(1).
1
8>

当我调用带有变量的函数时,是否有任何特殊原因必须使用模块名称?这对我不起作用,因为,一方面,它只是太多的语法垃圾,让我的眼睛流血。另一方面,我计划从列表中调用函数,例如(在我脑海中):

[X(1) || X <- [abs, f1, f2, f3...]].

尝试在此处添加各种模块名称会使冗长程度达到顶峰,而我所做的全部目的是减少冗长程度。

编辑:看这里:http://www.erlangpatterns.org/chain.html 这家伙做了一些管道转发功能。他以我想要的方式调用函数,但是当我尝试使用它时,他的代码不起作用。但据我所知,这家伙是一位经验丰富的 Erlang 程序员——我看到他在会议上发表了一些主题演讲或其他什么(我在网上看到的)。

这种事情过去有用但现在不行了吗?当然有一种方法可以让我做我想做的事 - 调用这些函数而不需要所有的冗长和样板。

编辑:如果我正确阅读了文档,这似乎意味着我在顶部的示例应该有效(第 8.6 节)http://erlang.org/doc/reference_manual/expressions.html

【问题讨论】:

  • X = abs, X(1). 不起作用,因为 Erlang 不认为绑定到变量的原子是函数。不过,X = erlang, Y = abs, X:Y(1). 应该可以工作。分隔两部分的冒号告诉 Erlang 这是一个函数。

标签: erlang


【解决方案1】:

我知道 abs 是一个原子,而不是一个函数。 [...] 为什么使用模块名称时它会起作用?

The documentation 解释说(略微重组):

ExprM:ExprF(Expr1,...,ExprN)

ExprMExprF 中的每一个都必须是一个原子或表达式 计算为一个原子。据说该函数是通过使用 完全限定的函数名。

ExprF(Expr1,...,ExprN)

ExprF 必须是原子或评估为乐趣。 如果 ExprF 是一个原子,则称该函数是通过使用隐式限定的函数名来调用的。

  • 使用完全限定的函数名时,Erlang 需要 atoms表达式,其计算结果为 atoms。换句话说,您必须将X 绑定到一个原子X = atom. 这正是您提供的。
  • 但在第二种形式中,Erlang 需要一个 atom 或一个计算结果为 函数表达式。注意最后一句话。换句话说,如果你使用完全限定的函数名,你必须将X绑定到一个函数:X = fun module:function/arity.

【讨论】:

  • “很清楚?”文档不是很清楚,实际上我在您之前在编辑中发布了相同的文档。我认为这令人困惑。话虽如此,我接受你的回答是正确的。
【解决方案2】:

在表达式X=abs 中,abs 不是函数而是原子。如果你想这样定义一个函数,你可以这样做:

D = fun erlang:abs/1.

左右:

X = fun(X)->abs(X) end.

【讨论】:

  • 补充细节:语法fun M:F/ArityArity被指定的原因是因为Erlang允许许多函数具有相同的名称。函数的 unique 部分是函数名 arity(它需要多少个参数)。因此,仅函数名称不足以知道使用了哪个函数;参数的名称和数量是必需的。
  • 我知道 abs 是一个原子,而不是一个函数。但是您使用原子作为名称来调用该函数。看看我上面的例子。为什么在使用模块名时会起作用?
  • @user3355020 ,经过模式匹配的操作后X就是字面意义上的abs相等。 IE。在哪里可以使用 atom abs 和 X. Cool,对吗?我喜欢 Erlang 的原因之一。
【解决方案3】:

试试:

X = fun(Number) -> abs(Number) end.

更新:

在查看了更多讨论之后,您似乎想要将多个函数应用于某些输入。

有两个项目我没有亲自使用过,但我在 Github 上出演了可能是您正在寻找的项目。

这两个项目都使用解析转换:

管道是独一无二的,因为它使用了一种特殊的语法:

Result = [fun1, mod2:fun2, fun3] (Arg1, Arg2).

当然,也可以编写自己的函数来使用{module, function} 元组的列表并将该函数应用于先前的输出,直到得到结果。

【讨论】:

  • 虽然这个答案可能是正确且有用的,但最好在其中附上一些解释来解释它如何帮助解决问题。如果有更改(可能不相关)导致它停止工作并且用户需要了解它曾经是如何工作的,这在未来变得特别有用。
  • 是的,我知道我可以这样做,但我不想那样做。我想要一个可以用来调用函数的原子列表。
  • @user3355020 是不同模块中的功能还是都在同一个模块中?
  • 它们可能位于不同的模块中。
  • @user3355020 我用一些您可能有兴趣将输入应用于函数列表的项目更新了我的答案。
猜你喜欢
  • 2023-04-03
  • 2013-02-28
  • 2016-05-18
  • 2014-10-20
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多