【问题标题】:Haskell compiler magic: what requires a special treatment from the compiler?Haskell 编译器魔法:编译器需要特殊处理什么?
【发布时间】:2016-03-02 00:56:16
【问题描述】:

在尝试学习 Haskell 时,出现的困难之一是当某些事情需要编译器提供特殊魔法时的能力。想到的一个例子是无法定义的seq 函数,即您不能使seq2 函数的行为与内置seq 完全相同。因此,在向某人介绍seq 时,您需要提及seq 是特殊的,因为它是编译器的特殊符号。

另一个例子是 do-notation,它只适用于 Monad 类的实例。

有时,这并不总是显而易见的。例如,延续。编译器是否知道 Control.Monad.Cont 或者您可以自己发明的普通的旧 Haskell?在这种情况下,我认为编译器不需要什么特别的东西,即使延续是一种非常奇怪的野兽。

抛开语言扩展,Haskell 学习者应该注意哪些其他编译器魔法?

【问题讨论】:

  • 显而易见:IO 任何合理的“魔法”定义都属于“魔法”:reddit.com/r/haskell/comments/450baq/…。还有ST monad,这可能更神奇。
  • STM 怎么样?和流融合?
  • 我不确定我是否会称之为流融合魔法。您可以创建自己的重写规则,因此这更像是语言的工具而不是魔法(至少在 GHC 扩展的 Haskell 中)。此外,如果事情是间接的、间接的魔法,只是因为他们使用了其他魔法,那么看起来几乎所有东西都是魔法,因为你最终最终会到达IO。当然,STM 可能更偏向于魔法方面,因为它可能在某些时候在内部直接使用像 State# RealWorld 这样的东西。
  • GHC 开发人员通常称之为“魔法”的东西是那些从编译器得到特殊处理的东西。 Coercible(定义为data,并神奇地更改为k -> k -> Constraint)和lazy(“神奇地”使GHC认为函数是惰性的)就是很好的例子。
  • 请参阅here 了解 GHC 源代码中定义原始标识符(即函数)的部分。也许唯一令人惊讶的原始事物是($) :: (a -> b) -> (a -> b)

标签: haskell ghc


【解决方案1】:

几乎所有不能在用户空间中实现的 ghc 原语都在 ghc-prim 包中。 (它甚至还有一个名为 GHC.Magic 的模块!)

所以浏览一下会很有感觉。

请注意,除非您确切知道自己在做什么,否则您应该不要在用户空间代码中使用此模块。其中大部分可用的东西都以base 的形式导出到下游模块中,有时以修改后的形式。这些下游位置和 API 被认为更稳定,而 ghc-prim 不保证它在不同版本之间的行为方式。

特定于 GHC 的内容在 GHC.Exts 中重新导出,但许多其他内容进入 Prelude(例如基本数据类型,以及 seq)或并发库等。

【讨论】:

    【解决方案2】:

    多态seq 绝对是神奇的。您可以为任何特定类型实现seq,但只有编译器可以为所有可能的类型实现一个函数[并避免优化它即使它看起来没有操作]。

    显然,整个 IO monad 非常神奇,并发和并行性(parforkIOMVar)、可变存储、异常抛出和捕获、查询垃圾收集器和运行-时间统计等。

    IO monad 可以被认为是ST monad 的一个特例,这也是一个神奇的例子。 (它允许真正可变的存储,这需要低级的东西。)

    另一方面,State monad 是完全普通的用户级代码,任何人都可以编写。 Cont monad 也是如此。各种异常/错误单子也是如此。

    与语法(do-blocks、list comprehensions)有关的任何事情都被硬连接到语言定义中。 (但请注意,其中一些响应LANGUAGE RebindableSyntax,这使您可以更改它绑定到的功能。)还有deriving 的东西;编译器“知道”一些特殊类以及如何为它们自动生成实例。 newtype 的派生适用于 any 类。 (它只是将实例从一种类型复制到该类型的另一个相同副本。)

    数组是硬连线的。就像所有其他编程语言一样。

    所有的外来函数接口显然都是硬连线的。

    STM 可以在用户代码中实现(我已经做到了),但它目前是硬连线的。 (我想这会带来显着的性能优势。我还没有尝试过实际测量它。)但是,从概念上讲,这只是一种优化。您可以使用现有的低级并发原语来实现它。

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      相关资源
      最近更新 更多