问题标签 [multiple-dispatch]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
77 浏览

c# - C#:System.Type 不是真正的类型吗?或:解决单一调度问题

我一直在尝试解决没有基于方法参数类型的多态分派的 C#,并且我遇到过您无法传递类型。

我基本上有一个Model实现两种方法的抽象类:IEnumerable<Decision> GetDecisions()void TakeDecision(Decision decision). Decision也是一个抽象类。这个类的消费者反复获得可能的决定,评估它们并将最好的决定传回给Model.

每个单独的派生模型都可以处理一些常见的决策和一些特定于模型的决策,并且我为每个特定类型可以使用的单独的TakeDecision()方法。问题当然是单次调度。理想情况下,消费者会这样做:DecisionModel

var m = ModelFactory.GetModel(some parameters); //m is type Model var ds = m.GetDecisions(); //ds is IEnumerable<Decision> //Some logic here to choose the best Decision d m.TakeDecision(d);

现在我必须在每个 derived 中实现看起来像这样的逻辑Model,因为 C# 可以分派到正确的Model实现,但不能分派到正确的重载:

if (decision is FooDecision) TakeDecision((FooDecision)decision); if (decision is BarDecision) TakeDecision((BarDecision)decision); ...

或者我强迫消费者站在他们这边进行选角(他们很可能已经这样做了以检查决定)。

我想System.Type在每个派生类中有一个 s 列表,所以我可以这样做:

foreach (var t in AllowedDecisionTypes) { if (decision is t) TakeDecision((t)decision); }

但它看起来System.Type不是真正的类型:

  1. 你不能这样做:AllowedDecisionTypes.Add(FooDecision),但你可以这样做AllowedDecisionTypes((new FooDecision()).GetType())
  2. 反之亦然,你不能做decision is AllowedDecisionTypes[0],但你可以做decision is FooDecision

有没有办法两者兼得?即,生成类型列表并转换为它们?还是void Decision.ApplyTo(Model model) { model.TakeDecision(this); }在每个决定上进行双重调度和实施的唯一方法,这可能应该调度到正确的重载,因为this现在是特定的Decision

0 投票
1 回答
157 浏览

arrays - How can I specify a type for a function argument without restricting its dimensions?

In Julia, I want to specify the type of a function argument as an array of arrays. So I have

but if I set the argument x in the REPL, for example:

then it automatically gets the following type assignment (for example), which includes its dimensions:

so that I get the error

I don't want to restrict the array dimensions at all, so was thinking that the solution maybe something along the lines of

but this doesn't work either.

How can I specify the argument type to be an array of arrays?

0 投票
3 回答
751 浏览

c++ - 具有完全可维护性的多调度解决方案

有人能想出一个好方法来实现像Object::foo下面的重载这样的多重调度吗?

我正在执行多次调度的客户端代码如下所示:

您可以通过我的设计推断出我的解决方案在维护类别中惨遭失败。每次要多次分派具有重载的新函数时,都需要编写新的相应访问者类等...(例如,在这种情况下ObjectFooVisitor,函数等...)。Object::fooMultipleDispatch理想的设计不应该需要这种类型的维护工作。

一个示例访问者函数,我刚刚多次调度 Object::foo,如下所示:

所以我遵循的主要思想是存储一个动态类型指针数组的元组,然后使用这个存储来调用适当的重载。但必须有其他设计才能让这个工作更好。

如果您想查看它,这是我的完整解决方案(在 GCC 4.9.2 上编译,需要 SFINAE 支持)。随意尝试改进它,使其更易于维护,但我确信需要一个新的设计。

0 投票
1 回答
801 浏览

julia - 在两个文件中重载一个函数(在 Julia 中)

我将用一个最小的例子来解释我的问题。假设我有三个文件:

A.jl

B.jl

主要.jl

在这里,我有两个版本的f功能。如果我正确理解了多分派的概念,应该在运行时扣除应该使用哪个版本。因此,我预计运行 Main.jl 会打印f called with A。不幸的是,我得到

如果我注释掉using B,它工作正常。显然,f从 B.jl 覆盖f了从 A.jl。

所以,问题是:问题出在哪里?在我的方法中还是在我使用的 Julia 版本中(0.3.7)?我该如何规避这个?

请注意,替换using Aimport A使用完全限定名称(例如A.f)不是一个好的解决方案。它与多重分派的症结相矛盾——在编译时我不知道是否应该使用A.for B.f

0 投票
3 回答
634 浏览

oop - 多次调度:概念上的必要性?

我想知道多重分派的概念(即内置支持,就好像虚拟方法的动态分派也扩展到方法的参数一样)是否应该包含在面向对象的语言中,如果它对性能的影响是微不足道。

问题

考虑以下场景:我有一个——不一定是扁平的——包含动物类型的类层次结构。在我的代码中的不同位置,我想对动物对象执行一些操作。我不关心,也无法控制如何获得这个对象引用。我可能会通过遍历动物列表遇到它,或者它可能作为方法的参数之一提供给我。我要执行的操作应该根据给定动物的运行时类型进行专门化。此类行动的示例包括:

  • 为动物构建一个视图模型,以便在 GUI 中显示它。
  • 构造一个表示这种动物的数据对象(稍后存储到数据库中)。
  • 给动物喂一些食物,但根据动物的类型给予不同种类的食物(什么对它更健康)

所有这些例子都在动物对象的公共 API 上操作,但它们所做的不是动物自己的事情,因此不能放入动物本身。

解决方案

一种“解决方案”是执行类型检查。但是这种方法容易出错并且使用反射特性,这(在我看来)几乎总是表明设计不好。类型应该只是一个编译时概念。

另一种解决方案是“滥用”(某种程度)访问者模式来模仿双重调度。但这需要我改变我的动物以接受访客。

我相信还有其他方法。另外,扩展的问题要解决:如果有新类型的动物加入聚会,需要调整多少代码位置,如何可靠地找到它们?

问题

那么,鉴于这些要求,多重分派不应该是任何设计良好的面向对象语言的一个组成部分吗?
使外部(不仅仅是内部)动作依赖于给定对象的动态类型不是很自然吗?

此致!

0 投票
1 回答
1544 浏览

julia - Julia 是如何实现多方法的?

我一直在阅读http://c2.com/cgi/wiki?ImplementingMultipleDispatch

我一直在寻找有关 Julia 如何实现多方法的参考资料时遇到了一些麻烦。调度的运行时复杂度是多少,它是如何实现的?

0 投票
5 回答
145 浏览

java - Java 是否支持像 Lisp 那样基于多个对象的类型分派到特定的实现?

将自己读入 Lisp,目前在此页面 ( http://landoflisp.com ) 上,我在单击链接CLOS GUILD时显示的页面的倒数第二段中找到了以下语句:

关于该示例需要注意的重要一点是,为了确定在给定情况下调用哪个 mix 方法,CLOS 需要考虑传入该方法的两个对象。它根据多个对象的类型分派到方法的特定实现。这是传统面向对象语言(如 Java 或 C++)中不具备的功能。

这是示例 Lisp 代码:

不,我认为最后一句话是错误的。实际上,我可以使用以下 Java 代码做到这一点:

当我运行它时,它给了我相同的输出:

所以我的问题是:该页面上的这句话实际上是错误的吗?在 Java / C++ 中可能吗?如果是这样,也许在旧版本的 Java 中是不可能的?(虽然我非常怀疑,因为这本书只有 5 年的历史)如果不是这样,我在我的例子中忘记考虑什么?

0 投票
1 回答
1038 浏览

julia - Julia中类方法的多次调度

我的问题是如何在 Julia 的某个类中重载某些方法

换句话说,假设我有一个类的以下定义:

所以当我在我的主要代码中说:

根据val标量向量还是矩阵,它会调用相应版本的setvalue方法。现在,使用上面的定义,它会覆盖setvalue最后一个(在这种情况下为矩阵版本)的定义。

0 投票
1 回答
115 浏览

c++ - 多态性和切片与引用

我没有完全理解 C++ 中的对象切片。在下面的示例代码中,两个对象似乎接受了相同的处理,但多态性仅适用于其中一个。

我正在使用引用,其中一个对象似乎没有被切片。我相信在 launch_ship 函数调用期间一定会发生一些事情,但我不知道到底出了什么问题。

这是示例代码。

输出:不想操作那艘低矮的飞船!

0 投票
1 回答
126 浏览

f# - 如何在字典中编码不同类型的多个函数

我正在用 F# 构建一个解释器。我试图变得聪明并将原始运算符的解释概括为函数调用(在这种情况下,作为归约)。

这是这样的想法:

所以我以后可以这样做:

当然,类型检查器会拒绝这个

警告 FS0064:此构造导致代码的通用性低于类型注释所指示的通用性。类型变量 'T 已被限制为类型 ''a -> 'a -> 'a'。错误 FS0001:类型不匹配。期待 ('a -> 'a -> 'a) -> ('a -> 'a -> 'a) -> 'a -> 'a -> 'a 但给定一个 ('a -> 'a -> 'a) -> 'a 当统一 ''a' 和 '('a -> 'a -> 'a) -> 'a -> 'a -> 'a' 时,结果类型将是无限的

PD:作为一个简单的解释器,我知道如何做到这一点,但我试图构建一个解决方案,让我以通用的方式构建数十种方法,而无需为每个方法制作 MATCH。