【问题标题】:Why does Erlang allow putting parentheses after a fun?为什么 Erlang 允许在 fun 后面加上括号?
【发布时间】:2018-05-03 02:19:57
【问题描述】:

这个问题是关于一个合作伙伴今天遇到的一些语法,虽然我们了解它的工作原理,但我们不明白为什么允许它(它的用途是什么?)。

看看这个sn-p:

fun() -> ok end().

如果没有最后一对括号,这将产生如下内容:

#Fun<erl_eval.20.82930912>

但是有了它们,函数被评估产生:

ok

我的问题是,为什么 Erlang 允许使用这种语法?为什么我要创建一个函数来立即调用它而不是写出它的内容?有什么实际用途吗?

我们唯一能想到的就是在 fun 的主体中引入局部变量(但这对我来说看起来很丑陋和不清楚)。

请注意,这种其他语法在 Erlang 中是不允许的,即使它遵循与前者相同的概念:

fun() -> fun() -> ok end end()().  

(这意味着:一个函数 A 返回一个函数 B。我正在评估 A(从而产生 B),然后评估 B 以获得'ok')。

【问题讨论】:

  • 我不了解 Erlang,但(我认为)函数是一流的对象。这意味着它们可以是函数的参数,可以分配给变量,甚至可以是返回值本身。当您执行诸如按自定义功能进行排序之类的操作时,它非常有用。见stackoverflow.com/questions/245192/what-are-first-class-objects
  • 关于最后一个,你可能错了。至少我的 erlang 版本适用于 fun() -&gt; fun() -&gt; ok end() end(). 我的意思是该陈述是正确的。
  • @rogaos 是的,它们是 Erlang 中的一等对象。但是为什么不允许第二种语法呢? (乐趣归还乐趣)。
  • @ipinak 注意两对括号是如何放在我的版本的第二个end 的末尾的。
  • @DWilches 我不太明白你的回复。

标签: erlang


【解决方案1】:

您提到的语法是 Erlang 功能化的自然结果。

在 Erlang 中,函数是值(存储为闭包)。

fun() -&gt; ok end 的值是一个函数,它不接受任何内容并返回ok。当我们在它后面加上括号时,我们正在调用该函数。另一种证明这一点的方法是:

 > F = fun() -> ok end.  
 #Fun<erl_eval.20.80484245>
 > F().                  
 ok

您的第二个示例中的函数需要正确分组,以便解析器理解它们。

至于您的问题——“为什么允许使用这种语法”,我不得不说这是 Erlang 中作为值的函数的自然结果。这种能力使编程的功能风格成为可能。这是一个例子:

 > lists:map(fun(X) -> X * 2 end, [1,2,3]).
 [2,4,6]

上面的代码本质上是这样的:

 > [fun(X) -> X * 2 end(1), fun(X) -> X * 2 end(2), fun(X) -> X * 2 end(3)].
 [2,4,6]

“自然结果”只是自然结果,它实际上不必有任何实际用途。所以,你可能永远不会看到像(fun() -&gt; fun() -&gt; ok end end())(). 这样的代码被使用:)

【讨论】:

    【解决方案2】:

    您通常不会对语法 fun() -&gt; ok end () 有太多用处。但是像(find_right_fun()) () 这样的操作可能很有用,它基本上是相同的——一个计算为函数的表达式。

    请注意,Erlang 解析器要求您使用 () 指定优先级来整理 ()() 的含义,即您的第二个示例应该是 (fun() -&gt; fun() -&gt; ok end end()) ()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-05
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多