参数值(不是类型)的多态性



是否有一种编程语言(可能是概念或研究论文(,它允许函数/方法参数值的多态性?有点:

function factorial(int value > 0){ /* code here */}
function factorial(int value == 0){ /* code here */}
function factorial(int value < 0){ /* code here */}

而且,这种多态性的官方名称(如果有的话(是什么?

我想你要找的是模式匹配和/或守卫。例如,Erlang 允许这样做:

foo(X) when X > 0  -> bar(X);
foo(X) when X == 0 -> baz(X);
foo(X)             -> X.
foo("bar", X) -> bar(X);
foo(42, X)    -> baz(X);
foo(_, X)     -> X.

前者演示了守卫的使用,后者是一个简单的模式匹配,其中第一个参数要么是"bar",要么是42,要么是其他任何东西。这两种技术都可以在许多函数式语言中找到。

以防万一您不熟悉语法,这相当于(尽可能多

地进行比较(:
function foo("bar", x) {
    return bar(x);
}
function foo(42, x) {
    return baz(x);
}
...

Matthias Blume在2006年发表了一篇名为"Extensible Programming with First-Class Cases"的论文,讨论了这样一个系统(基于ML,IIRC(。

你也许可以用一些面向方面的语言(如AspectJ(做同样的事情,但我还没有尝试过。

此外,在像 Scheme 这样同时支持一等函数和绑定到函数的名称突变的语言中,您可以通过包装旧版本来扩展函数:

(define (factorial n)
  1)
(factorial 0) ;; => 1
(factorial 5) ;; => 1
(set! factorial
  (let ([old-factorial factorial])
    (lambda (n)
      (cond [(> n 1)
             (+ (factorial (- n 1)) (factorial (- n 2)))]
            [else
             (old-factorial n)]))))
(factorial 0) ;; => 1
(factorial 5) ;; => 8
(factorial 6) ;; => 13

重新定义函数可以进行调试,但对于"真实代码"不屑一顾,并且某些模块系统不允许更改模块导出。在这种情况下,另一种方法是拥有一个包含案例列表的私有可变变量;main 函数显式遍历案例,并且有一个单独的函数用于添加案例。

模式匹配和防护是实现此目的的一种方法;OCaml,Haskell和Scala也都提供了它们。

Prolog具有类似的功能:您可以定义依赖于特定值的关系。例如:

factorial(X, 0) :- X =< 0, !.
factorial(1, 1).
factorial(X, Y) :- X2 is X - 1, factorial(X2, Z), Y is X * Z.

在此代码中,我们定义了一个factorial关系,使得当 Y=X!时满足factorial(X,Y);为此,我们将其专门化为三种情况,一种涉及特定值,另一种涉及范围测试。

是的,Prolog真的很奇怪。编程包括写下真实的陈述;然后,您向系统查询特定语句或使语句为真的变量赋值的真实性。例如,如果上面的代码保存在factorial.pl

?- consult(factorial).
% factorial compiled 0.00 sec, 2,072 bytes
true.
?- factorial(3, 6).
true .
?- factorial(5, X).
X = 120 .
?- factorial(4, 25).
false.

最新更新