问题标签 [overlapping-instances]

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 回答
365 浏览

haskell - Show 的重叠实例

假设我们有以下内容:

使用此代码,ghc 抱怨:

我可以理解它认为类型a可以派生Show或派生ListContainer,这可能会导致Show.

我们如何避免这种情况?

我知道存在一个 function showList,但它的签名有点陌生。我已经有一个函数,我打算用来显示某些列表,它String直接返回。

0 投票
1 回答
74 浏览

haskell - 为什么使用具有重叠实例的类型类的此函数在 GHCi 中表现不同?

背景

我在 Haskell (GHC 8.6.3) 中编写了以下代码:

这段代码背后的想法是产生一个可变参数的函数,它接受它的参数并将它们打包到一个异构列表中。

例如,以下

产生列表Cons "a" (Cons "b" nil)

问题

一般来说,我想fpack通过id作为f参数传递来调用(如上),所以我希望将以下函数定义为简写:

如果我将上面的程序加载到 GHCi 并执行上面的行,pack 会根据需要定义,并且它的类型(由 给出:t)是FPack (a -> a) r => r. 所以我在我的程序中定义了这样的函数:

但这在将所述程序加载到 GHCi 时会出现以下错误:

这引出了我的问题。为什么这个函数在 GHCi 中定义时有效,但在程序中定义时无效?有没有办法让我在程序中正常工作?如果是这样,怎么做?

我的想法

根据我对 GHC 和 Haskell 的了解,这个错误来自于pack可以解决两个重叠实例中的任何一个的事实,这会困扰 GHC。但是,我认为该AllowAmbiguousTypes选项应该通过将实例选择推迟到最终调用站点来解决该问题。不幸的是,这显然还不够。我很好奇为什么,但我更好奇为什么 GHCi 在它的 REPL 循环中接受这个定义,但是当它在程序中时它不接受它。

切线

我有另一个关于这个程序的问题,它与这个问题的主旨没有直接关系,但我认为在这里问它可能是明智的,而不是就同一个程序创建另一个问题。

如上面的示例所示,即

我必须提供一个明确的类型签名fpack才能使其按需要工作。如果我不提供(即只调用fpack id "a" "b"),GHCi 会产生以下错误:

有什么办法可以改变的定义fpack让 GHC 推断出正确的类型签名?

0 投票
1 回答
44 浏览

haskell - 递归列表变换中重叠实例的行为

在我的递归列表转换中,重叠实例的优先级没有按预期进行。

我正在尝试创建一个对任意深度的嵌套列表进行操作的转置函数。目标是有两个函数,一个可以将“最高维度”向下转换为“最低维度”,即维度为 [a, b, c] 的嵌套列表将转换为维度为 [ b, c, a] 和一个相反的,[a, b, c] 到 [c, a, b]。

我的意图是第一个实例应用于所有嵌套列表,第二个实例应用于其他所有内容。

以下是一些测试示例,“ref”表示函数的预期行为

然而,参考和测试的结果是不同的,例如:

我没有太多使用重叠实例的经验,所以我不确定如何选择实例。对我来说,似乎转置只发生在第一个“层”中,之后使用第二个实例(id)。这有效地把它变成了正常的转置,这不是很有趣。

0 投票
4 回答
165 浏览

haskell - 重叠多参数实例和实例特异性

既不编译aretheyreallyeq也不aretheyeq编译,但是 for 的错误对aretheyreallyeq我来说是有意义的,并且还告诉我不aretheyeq应该给出错误:GHCi 建议的可能 for EqMin的实例之一aretheyeq应该是不可能的,因为aretheyreallyeq. 这是怎么回事?

关键是,GHCi 坚持认为 的两个实例EqM都适用于aretheyeq. But a1is of typeab2is of type b,所以为了使第一个实例适用,它必须具有类型ab统一。

但这应该是不可能的,因为它们在函数签名处被声明为类型变量(也就是说,使用第一个EqM实例会导致函数为 type Either a a -> Either a a -> Bool,并且aretheyreallyeq告诉我 GHCi 不允许这样做(无论如何都是我所期望的)。

我是否遗漏了什么,或者这是如何检查具有多参数类型类的重叠实例的错误?

我在想这可能与这样一个事实有关,a并且b以后可以进一步实例化到它们相等的点, outside aretheyeq,然后第一个实例有效的?但对于aretheyreallyeq. 唯一的区别是,如果他们不统一,我们可以选择aretheyeq,但我们没有aretheyreallyeq。在任何情况下,Haskell 没有动态调度有很多好的和明显的原因,所以有什么害怕提交实例总是有效的,无论以后a是否b统一也许有某种方法可以在以某种方式调用函数时选择实例?

值得注意的是,如果我删除第二个实例,那么该函数显然仍然无法编译,说明找不到实例EqM a b。因此,如果我没有那个实例,那么没有一个有效,但是当那个有效时,突然另一个也有效并且我有重叠?几英里外的我闻起来像虫子。

0 投票
0 回答
162 浏览

haskell - Multi-way FunDeps 和重叠实例的一致性:(为什么)这行得通?

这是旧栗子的变种。我写它期望它不起作用,但它确实起作用了。还是很狡猾?(在 GHC 8.6.5 时。)

传统上, class 上只有两个 FunDeps AddNat,第二个实例是

Functional dependencies conflict between instance declarations:如果有 FunDep ,该实例将被拒绝b c -> a。事实上,该OVERLAPPABLE实例正在利用 GHC 的虚假 FunDep 一致性检查

但是没有那个 FunDep,subNat就无法从参数中推断出它的结果:Ambiguous type variable 'a0'. 我猜我的测试有效,因为参数的类型是subNat完全已知的。如果它们是部分已知的,类型改进将陷入无法拒绝ZNat b b实例的困境。

Oleg Kiselyov 的 ftp 站点曾经有一个类用于 3 向改进添加自然,但它有一个复杂的辅助超类约束和辅助实例的复杂巢穴,基本上重复了中心类。我所做的似乎太简单了。哪里会出错?

0 投票
1 回答
62 浏览

haskell - 对“冲突的家庭实例声明”感到困惑

我收到一个我不太理解的冲突家庭实例错误:

结果是

n并不比[a]因为Num n实例头中的约束更通用。这些对我来说似乎并不矛盾。Num如果我实施for以后可能会出现冲突的问题[a]吗?如果是这样,任何两个实例都不会存在这种潜在的冲突吗?

功能依赖会以类型族不允许的方式允许这样做吗?

完整代码如下:

0 投票
1 回答
127 浏览

haskell - Haskell - 重叠实例和转换类型类

我正在编写代码以通过数学逻辑中的定义来实现扩展。

它接受语言及其扩展的描述,并输出一个新的 haskell 文件,该文件会将高级语言解析为低级语言。当然,如果我能把C语言变成B语言,B语言变成A语言,那么通过作曲我就可以把C语言变成A语言……然而……

这是我面临的问题的一个最小示例:

直觉上, 没有什么问题instance (ToB a) => ToA a,但编译器不喜欢它。代码按原样编译,但在用ToA C注释版本替换显式实例后,我收到以下错误:

当然,我不害怕语言扩展,所以我按照我的指示去做并添加了 FlexibleInstances,尽管我认为它在这里没有帮助。完成此操作后,我被告知尝试 UndecidableInstances ......这就是线索停止的地方。我仍然收到类型错误,但我不确定该怎么做。

这个错误信息让我特别困惑,因为我只有一个ToA B. 如果这个错误B本身是 的一个实例ToB,比如通过设置convertToB = id. 当然,这里不是这样的……

我应该如何正确处理这个问题?提前致谢!^_^

0 投票
1 回答
183 浏览

haskell - 多个重叠实例的交互

模块Type.hs定义了谐音newtype,只导出其类型构造函数,不导出值构造函数,避免暴露细节;它还提供了一个构造函数makeType来平衡缺少值ctor。为什么我需要将 a 包装成String一个新类型?因为我希望它不仅仅是一个String; 在我的具体情况下,Type实际上被称为Line,并且对应于makeType强制它只包含一个\n,作为最后一个字符。Anewtype对我来说似乎是最明显的选择。如果不是这样,请原谅我:我正在学习。

为了以Type我喜欢的方式显示类型的值(例如,给定我的实际用例Line,我可能想\n用一个漂亮的 unicode 字符或序列<NL>或其他方式表示),我创建了另一个模块TypeShow.hs,我稍后(在尝试做我所描述的事情时)我通过添加一些编译指示进行了编辑。为什么是另一个模块?因为我猜某些东西在内部的运作方式和我在屏幕上展示它的方式是两个独立的方面。我错了吗?

除了这对模块(描述 的核心Type,以及它应该如何显示)之外,我还创建了其他类似的对Type1/ Type1ShowType2/ Type2Show,它们都包裹 aString来表示和显示其他类似String实体。

Type由于其他原因,我还需要另一种包装可选值的类型,它可以是Type1, 或任何其他类型,所以我编写了这个模块

(实际上Wrapper实际上包装了多个Type值,但我会避免提供更多必要的细节;如果以下内容很愚蠢,因为我只在 中包装了一个TypeWrapper,那么请考虑它实际上包装了多个值。)同样,在这里我试图隐藏细节,Wrapper同时提供makeWrapper制作一个,并getInside对其内部进行“受控”访问。

我也想在屏幕上显示这个,所以我创建了一个相应的WrapperShow.hs模块,所以它Wrappershow方法依赖于内容的show方法。

然而,此时,当类型a为 a时Maybe Type,我想显示Wrapper打印空字符串的内容,而不是Nothing,或 ; 的内容Just。因此,我写了instance Show (Maybe Type)我在上面评论过的内容。

鉴于此,Type "hello"andJust $ Type "hello"都正确显示为Type,但Wrapper $ Just $ Type "hello"显示为Just Type,就像它使用Maybe的原始实例一样,无论对于( )Show中的这种特定类型,我已经自定义了实例。MaybeTypeShow

0 投票
1 回答
76 浏览

haskell - 有没有一种方法可以多态地提升具有 monad 类型变量的类的实例,而不会重叠实例?

这个问题可以认为是后续问题

将具有“MonadIO”类型变量的类实例提升到转换后的 monad

其中提供了一个应用程序的示例,该示例将在何处使用。

这个想法是一个类型类

存在,在不同的 monad 中有基本实例

. 我想要的是一种将任何实例提升到自身或在变压器堆栈中更高的方法,就像liftIOIO. 我最初的想法是定义一个提升实例

然而,当应用多个转换器时,这会产生重叠实例的问题,就像lift多态一样,并且可以替换为,例如lift . lift.

建议改用类似的默认实例,

然后可以用来声明提升实例

. 这可行,但是需要为每个基本实例声明提升实例,所以我很好奇;有没有其他方法可以在不使用重叠实例的情况下解决这个问题?

0 投票
1 回答
50 浏览

haskell - 如何将重叠编译指示应用于派生实例

Pragma OverlappingInstances 在 GHC 中被弃用了一段时间,而 OVERLAPPING pragma 是它的替代品。

虽然这不是 Haskell 中定义类实例的唯一方法。我无法通过派生来定义重叠实例,并避免对已弃用的 OverlappingInstances 发出讨厌的警告。

以下情况均无效: