Erlang函数模式匹配

5
作为几乎是纯函数式编程语言的Erlang,我认为这是可能的:
case X of
    foo(Z) -> ...
end.

其中foo(Z)是一个可判定可逆的纯函数(无副作用),例如:

foo(input) -> output.

那么,在X = output的情况下,Z将匹配为input

在Erlang中是否可以使用这样的语义,无论是在我的示例中还是在其他语法之外?

4个回答

4

很抱歉,您想要的是不可能的。

要做到这样的事情,您需要能够找到任何双射函数的反函数,这显然是不可判定的。


3
我知道双射函数是什么。但是,仅因为每个双射函数都有一个反函数并不意味着你可以编写算法来找到它(你无法这样做)。 - sepp2k
我会编辑问题:一个可逆的纯双射函数。 - Pindatjuh

2

我猜不允许这样做的原因是您想要保证没有副作用。考虑以下结构:

case Expr of
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end

在评估完Expr之后,模式将顺序匹配Expr的结果。想象一下你的foo/1函数包含一个副作用(例如发送消息):

foo(input) ->
  some_process ! some_msg,
  output.

即使第一个模式不匹配,您仍将发送消息,而且无法从该情况中恢复。

谢谢,不过我所说的“纯函数”是指不允许有副作用。我会编辑问题的。 - Pindatjuh
1
我理解这一点。然而,问题在于如何确保用户定义的函数是纯函数。 - Roberto Aloi

1

不,Erlang只支持字面模式!

而且你的原始请求并不容易。仅仅因为存在一个反函数,并不意味着它很容易找到。实际上,编译器需要制作两个版本的函数。


1
你可以做的是:
Y = foo(Z),
case X of
  Y -> ...
end.

2
这需要你知道Z的值。我很确定这不是原帖作者想要的。 - sepp2k
如果将 foo 替换为 foo_inverse,这是有意义的。但正如 sepp2k 所说,这不是我想要的。 - Pindatjuh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接