功能上相当于重载
在函数式编程中我应该采取什么方法来重载方法(提供一个或多个具有相同函数名称的不同签名)。
我是函数式编程的新手,所以目前我还没有真正理解这一点。
例如,在 C# 中,我有以下内容:
public int LowestCommonMultiple(int a, int b)
{
return (a * b) / GreatestCommonFactor(a, b); // details ommited
}
public int LowestCommonMultiple(List<int> integers)
{
int commonMultiple = integers[0];
foreach(var integer in integers)
{
commonMultiple = LowestCommonMultiple(commonMultiple, i);
}
return commonMultiple;
}
谢谢,
编辑:我不需要 C# 中的答案,我的问题更多的是函数式 pargadim 问题,例如,在 Haskell 中考虑它。我认为重载方法不是一种选择。
What is the approach I should be taking in functional programming to overload a method (provide one or more different signatures with the same function name).
I'm new to functional programming, so I don't really get my head around this at the moment.
For example, in C# I'd have the following:
public int LowestCommonMultiple(int a, int b)
{
return (a * b) / GreatestCommonFactor(a, b); // details ommited
}
public int LowestCommonMultiple(List<int> integers)
{
int commonMultiple = integers[0];
foreach(var integer in integers)
{
commonMultiple = LowestCommonMultiple(commonMultiple, i);
}
return commonMultiple;
}
Thanks,
EDIT: I don't need the answer in C#, my question is more a functional pargadim question, for example, consider it in Haskell. I assume overloading a method is not an option.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 Haskell 中,重载是使用类型类完成的。这与 C# 中的重载有很大不同,因为类型类与 C# 中的接口更相似,尽管它们也更强大*。
例如,要拥有一个能够接受
Integer
或Bool
的函数,您可以编写如下内容:在解释器中测试它,我们看到函数 foo 具有带有约束的类型。
这意味着该函数适用于我们为其定义了
Foo
实例的类型a
。如果我们尝试在没有此类实例的类型上使用它,我们会收到错误。
对于你的例子,我认为在 Haskell 中以这种方式重载这个函数不是很有用。事实上,标准库中的
lcm
函数已经被重载了。这意味着它适用于任何有 Integral 实例的类型。在本例中,这就是所有类似整数的类型,包括机器大小的
Int
、任意大小的Integer
以及其他类型,例如Int32
、Int64
等等。列表版本可以写为
foldl1' lcm
,因此可能不需要首先提供这样的重载。* 一方面,类型类实例与它们所应用的对象分开传递。这使得多重调度之类的事情变得更加清晰。这也意味着您可以重载函数的返回类型,这在 C# 中是不可能的。类型类也可以与类型构造函数一起使用;
Monad
也许是此类类型中最著名的示例。In Haskell, overloading is done using type classes. This is quite different from overloading in C#, as type classes are more similar to interfaces in C#, although they are also more powerful*.
For example, to have a function which will be able to accept either an
Integer
or aBool
, you can write something like this:Testing this out in the interpreter, we see that the function
foo
has a type with constraints.This means that the function will work for types
a
for which we have defined aFoo
instance.If we attempt to use it on a type for which there is no such instance, we get an error.
For your example, I don't think it's very useful to overload this function in such a way in Haskell. In fact, the
lcm
function in the standard library is already overloaded.This means that it will work on any type for which there is an
Integral
instance. In this case, that's all integer-like types, including the machine-sizedInt
, the arbitrary-sizeInteger
, and others such asInt32
,Int64
and so on.The list version can be written as
foldl1' lcm
, so there might not be much of a need to provide such an overload in the first place.* For one thing, type class instances are passed separately from the objects they apply to. This makes things like multiple dispatch a lot cleaner. This also means you can overload on the return type of a function, which would be impossible in C#. Type classes can also be used with type constructors;
Monad
is perhaps the most famous example of such a type class.我不确定你所说的函数式编程语言是什么意思,这似乎与任何编程语言的特定功能(例如,支持重载)有关,而不是它是函数式的还是面向对象的。例如,在 Javascript 中,它不受支持,但很容易模拟,因为 javascript 不需要传递参数并且不是强类型的。
答案将取决于所讨论语言的具体功能。
I'm not sure what you mean by a functional programming language, this seems to have to do with a specific feature of any programming language (e.g., is overloading supported) rather than whether it is functional or object-oriented. In Javascript, for example, it is not supported, but is easily simulated because javascript doesn't require parameters to be passed and isn't strongly typed.
The answer is going to be depend on the specific features of the language in question.
我认为你的问题与函数式编程与过程式/面向对象编程没有太大关系,而是与静态变量类型与动态变量类型有关。
以SML(ML的一种方言)和Scheme/Lisp为例。两种函数式语言,但是在 SML 中重载函数是理所当然的,而在Scheme 中则不可能(至少在我还在使用它时是这样)。
SML 是静态类型的(如 C/C++/JAVA 等),因此编译器使用变量类型作为签名的一部分并创建重载不是问题,就像任何 C 编译器为 C 代码创建它们一样。另一方面,Scheme 是动态类型的,因此编译器/解释器无法在编译时(在大多数情况下)根据其参数找出方法的签名。
你的问题是非常跨语言的(我什至不认为所有静态类型语言都支持函数/方法重载),所以它总是取决于你使用的语言(有时是实现)。
I don't think that your problem has much to do with functional vs procedural/OO programing but with static vs dynamic variable typing.
Take SML (a dialect of ML) and Scheme/Lisp for instance. Both functional languages, but it's a no brainer to overload a function in SML while it's impossible in Scheme (at least so it was when I was still using it).
SML is statically typed (like C/C++/JAVA etc.) and therefore it's not problem for the compiler to use the variable types as a part of the signature and create overloads just like you any C compiler would create them for C code. Scheme on the other hand is dynamically typed and therefore the compiler/interpreter can't figure out a signature for the method based on it's parameters at compile time (in most cases).
Your question is very language pacific (I don't even think that all statically typed languages support function/method overloading) so it'll always come down to what language (and sometimes implementation) are you using.
您可以通过一次重构编写任意数量的签名 - 不能有 2 个具有相同参数类型的签名。每个签名都可以有它自己的返回类型
you can write any count of signatures with one restruction - you can't have 2 signatures with equal parameter types. Every signature can have it's ow return type