可以在本地使用UndecidableInstances pragma对编译终止产生全局影响吗?

Pet*_*lák 29 haskell compilation ghc language-extension

假设Haskell库设计者UndecidableInstances出于某种原因决定使用它.图书馆编译得很好.现在假设某些程序使用该库(比如定义其类型类的某些实例),但不使用该扩展.是否会发生编译失败(不终止)?

如果出现这种情况,我会很高兴看到一个例子.例如,由于mtl使用UndecidableInstances了很多,是否可以编写依赖于mtl(或使用该扩展的任何其他标准库)的程序,不使用UndecidableInstances自身,但由于不可判断而无法编译?

Rom*_*aka 22

好问题!

一般来说,这当然是可能的.考虑这个模块:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances #-}

module M where

class C a b | a -> b where
  f :: a -> b

instance C a b => C [a] [b]
  where f = map f
Run Code Online (Sandbox Code Playgroud)

它编译本身就好了.但是,如果您导入此模块并定义

g x = x + f [x]
Run Code Online (Sandbox Code Playgroud)

你会得到

Context reduction stack overflow; size = 201
Use -fcontext-stack=N to increase stack size to N
  C [b] b
In the second argument of `(+)', namely `f [x]'
In the expression: x + f [x]
In an equation for `g': g x = x + f [x]
Run Code Online (Sandbox Code Playgroud)

关于mtl实例,我不知道这样的事情是如何可能的,但我也没有证明它不是.

  • 我正在玩你的解决方案,我设法将其切割为`C类,其中f :: a - > a`和`实例C [[a]] => C [a]其中f = id`,这不是除了`UndecidableInstances`之外,还需要任何其他扩展. (5认同)
  • 在检查它`mtl`之后,我相信不可能通过使用它来使编译器循环.它需要扩展的唯一原因是因为它的一些实例未通过[覆盖条件](http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/type-class-extensions.html#实例的规则).但条件背后的想法是满足的 - 所有rhs类型变量都可以从`mtl`的实例声明中推断出来. (4认同)
  • 确实如此,但似乎"UndecidableInstances"暗示着"FlexibleContexts". (4认同)