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)
# ...
如你所见,这个设计不是很好至少因为:
dim1, dim2, dim3 = set_dims(vars, degree)
行被一遍又一遍地重复。我可能会对这些提供者方法的签名说同样的话——但我们不要那么挑剔,至少我可以忍受:)。
set_dims
函数被额外应用一次:它的结果在 f2_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)
# ...
假设我们有以下设置(让它写成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)
# ...
如你所见,这个设计不是很好至少因为:
dim1, dim2, dim3 = set_dims(vars, degree)
行被一遍又一遍地重复。我可能会对这些提供者方法的签名说同样的话——但我们不要那么挑剔,至少我可以忍受:)。set_dims
函数被额外应用一次:它的结果在f2_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)
# ...