DRY 函数式编程:如何避免同一行代码出现在不同的高阶函数中

DRY functional programming: how to avoid the same line of code in different higher order functions

假设我们有以下设置(让它写成Python,虽然语言不是必需的):

def f1_provider(vars, degree):
    dim1, dim2, dim3 = set_dims(vars, degree)
    def f1(*args1):
        # ...
        # use vars and dims
        # ...
    return f1

def f2_provider(vars, degree):
    dim1, dim2, dim3 = set_dims(vars, degree)
    def f2(*args2):
        # ...
        # use vars and dims
        # ...
    return f2

def f3_provider(vars, degree):
    dim1, dim2, dim3 = set_dims(vars, degree)
    def f3(*args3):
        # ...
        # use vars and dims
        # ...
    return f3

# then use them somewhere:

def f1_user():
    # ...
    f1 = f1_provider(vars1, degree1)
    # ...
def f2_f3_user():
    # ...
    f2 = f2_provider(vars2, degree2)
    f3 = f3_provider(vars2, degree2)
    # ...

如你所见,这个设计不是很好至少因为:

如何以实用的方式对其进行返工?

如果我们在 OOP 中,应该引入一个 class,如 GeneralProvider,将 set_dims 调用放入其构造函数中,并使这些提供程序成为 public 方法。不,没那么有趣 :).

这个解决方案适合您吗?

def f1_provider(vars, degree, *dims):
    def f1(*args1):
        # ...
        # use vars and dims
        # ...
    return f1

def f2_provider(vars, degree, *dims):
    def f2(*args2):
        # ...
        # use vars and dims
        # ...
    return f2

def f3_provider(vars, degree, *dims):
    def f3(*args3):
        # ...
        # use vars and dims
        # ...
    return f3

# then use them somewhere:

def f1_user():
    # ...
    dim1, dim2, dim3 = set_dims(vars1, degree1)
    f1 = f1_provider(vars1, degree1, dim1, dim2, dim3)
    # ...
def f2_f3_user():
    # ...
    dim1, dim2, dim3 = set_dims(vars2, degree2)
    f2 = f2_provider(vars2, degree2, dim1, dim2, dim3)
    f3 = f3_provider(vars2, degree2, dim1, dim2, dim3)
    # ...

我认为这是一种解决方法,尽管它很丑陋。但理论上它应该有效)。我仍然会等待更好的解决方案!

def f1_provider(vars_, dim1, dim2, dim3):
    def f1(*args1):
        # ...
        # use vars_ and dims
        # ...
    return f1

def f2_provider(vars_, dim1, dim2, dim3):
    def f2(*args2):
        # ...
        # use vars_ and dims
        # ...
    return f2

def f3_provider(vars_, dim1, dim2, dim3):
    def f3(*args3):
        # ...
        # use vars_ and dims
        # ...
    return f3


def general_provider(providers, vars_, degree):
    dim1, dim2, dim3 = set_dims(vars_, degree)
    return [f_prov(vars_, dim1, dim2, dim3) for f_prov in providers]

# then use them somewhere:

def f1_user():
    # ...
    f1 = general_provider((f1_provider,), vars1, degree1)
    # ...
def f2_f3_user():
    # ...
    f2, f3 = general_provider((f2_provider, f3_provider), vars2, degree2)
    # ...