Haskell 元组构造函数 (GHC) 以及语言与其实现之间的分离

2024-01-01

当我意识到这一点时,哈斯克尔再次让我大吃一惊

(x,y)

只是语法糖

(,) x y

当然,我想将其扩展到更大的元组。但

(,) x ((,) y z)

Gave me

(x,(y,z))

这不是我想要的。一时兴起,我尝试了

(,,) x y z

它起作用了,给出了我想要的:

(x,y,z)

这就提出了一个问题:你能走多远?令我惊讶的是,似乎没有限制。以下所有操作符都是有效的操作符:

(,)
(,,)
(,,,)
(,,,,)
--etc
(,,,,,,,,,,,,,,)
(,,,,,,,,,,,,,,,)
--etc
(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)
--etc

这种行为令人惊奇,并引出了我的实际问题:它可以在我自己的函数中模拟吗?或者它只是元组运算符的 GHC 特定功能? 我认为是后者,因为我已经阅读了 haskell98 规范,并且 iirc 它说实现只需为最多 15 个项目定义元组运算符。而 GHC 则全力以赴,让您可以达到任意限制。

那么,是否有可能从 haskell 实现本身中定义这一系列运算符/函数,只使用类型系统和现有语言功能(声明、类型签名、函数定义等)?如果是这样,怎么办?或者这是不可能的,您必须查看编译器来找到该函数集合的支持框架?

这引出了一个更普遍的问题:Haskell 本身通过类型和函数定义、声明等支持了多少 Haskell;编译器/实现支持多少? (我知道 GHC 是用 Haskell 编写的,但这并不能回答问题)

也就是说,如果你要放弃标准库(包括前奏)并在原始 Haskell 中从头开始做所有事情;是否有可能仅使用最少的功能集来构建具有 GHC 所有功能的完整实现?为了使用 Haskell 构建 haskell 实现,您需要的最小语言功能集是什么?我是否可以放弃前奏然后完全地重建它manually来自 GHC 内部?如果你放弃了前奏并且不再导入任何东西,那么你还剩下什么可以处理呢?

看起来我好像在问一百万个问题,但他们实际上都在试图用不同的措辞来问同样的事情。尽力而为吧!


唉,元组并没有什么魔力。这是 GHC 使用的实现 http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.2.0.0/GHC-Tuple.html,为了让您了解发生的情况,这里是最后一个定义的来源:

data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__
  = (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__ j__

...yeah.

那么,是否有可能从 haskell 实现本身中定义这一系列运算符/函数,只使用类型系统和现有语言功能(声明、类型签名、函数定义等)?如果是这样,怎么办?或者这是不可能的,您必须查看编译器来找到该函数集合的支持框架?

不,没有办法以通用的方式定义这样的元组。常见模式纯粹是语法上的,不能在类型系统或其他系统中递归地完成任何操作。当然,您可以使用 Template Haskell 生成此类定义,但您仍然需要使用字符串操作单独生成每个定义来创建名称,而不是使用任何类型的共享结构。

还有一个问题是元组语法是内置的,无法模仿,但这是一个单独的问题。您可能会想象这样的类型:

data Tuple2 a b = Tuple2 a b
data Tuple3 a b c = Tuple3 a b c

...等等,它们不使用特殊语法,但由于上述原因仍然无法通用定义。

这引出了一个更普遍的问题:Haskell 本身通过类型和函数定义、声明等支持了多少 Haskell;编译器/实现支持多少? (我知道 GHC 是用 Haskell 编写的,但这并不能回答问题)

几乎所有的内容都是在 Haskell 中定义的。某些事物具有您无法模仿的特殊语法,但在大多数情况下,它们只会扩展到编译器特别注意某些定义。否则,两者之间没有区别this http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.2.0.0/src/GHC-Types.html:

data [] a = [] | a : [a]

...以及您自己定义的任何等效类型。

也就是说,如果你要放弃标准库(包括前奏)并在原始 Haskell 中从头开始做所有事情;是否有可能仅使用最少的功能集来构建具有 GHC 所有功能的完整实现?为了使用 Haskell 构建 haskell 实现,您需要的最小语言功能集是什么?我是否能够放弃前奏,然后从 GHC 中手动完全重建它?如果你放弃了前奏并且不再导入任何东西,那么你还剩下什么可以处理呢?

阅读有关 GHC 的内容可能会给您带来启发NoImplicitPrelude 和 RebindableSyntax http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#rebindable-syntax扩展,除其他外,它可以让您更改用于解释的定义do符号,如何处理数字文字,什么if then else语法确实如此,等等。

我只想说,非常非常少的事情是无法重新实现的。大多数不能的东西只是由于语法而特殊,并且可以用等效的东西替换(例如上面的列表和元组)。

最后,有一组有限的东西very特殊行为——IOtype 是一个明显的例子——你根本无法替换它,因为它们直接挂接到运行时系统中你无法替换的东西上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 元组构造函数 (GHC) 以及语言与其实现之间的分离 的相关文章

  • Data.Sequence 中的 inits 和 tails 如何工作?

    Louis Wasserman 编写了当前的实现inits and tails in Data Sequence 他表示它们非常高效 事实上 只要查看代码 我就可以看到 无论它们在做什么 它们都是以干净 自上而下的方式进行的 这往往会给惰性
  • Haskell:不在范围内:数据构造函数

    今天开始在学校学习 haskell 我遇到了函数问题 我不明白为什么它不在范围内 代码如下 ff Char gt Char gt Char ff A B x 0 y 1 x lt A y lt B x 1 y 0 和错误 md31 hs 2
  • 管道:多个流消费者

    我编写了一个程序来计算语料库中 NGram 的频率 我已经有一个函数 它消耗一串令牌并生成一个订单的 NGram ngram Monad m gt Int gt Conduit t m t trigrams ngram 3 countFre
  • C++ 概念与 Haskell 类型类有何不同?

    Concepts TS 中的 C 概念最近已合并到 GCC 主干中 概念允许人们通过要求类型满足概念的条件 例如 可比较 来约束通用代码 Haskell 有类型类 我对 Haskell 不太熟悉 概念和类型类如何相关 概念 由概念 TS 定
  • 关于“没有绑定的类型签名”的错误

    我在 Haskell 中遇到 ASCII 问题 fromEnum Char gt Int toEnum Int gt Char offset Int offset fromEnum A fromEnum a toUpper Char gt
  • 构造微积分中的“Refl”东西?

    在语言中 例如Agda Idris or Haskell对于类型扩展 有一个 键入类似于以下内容的内容 data a b where Refl a a a b意思是a and b是相同的 这样的类型可以定义在结构演算 https en wi
  • 为什么在 where 子句中使用类型签名如此罕见?

    它是否有助于编译器优化 或者只是添加额外类型签名的多余工作 例如 人们经常看到 foo a gt b foo x bar x where bar x undefined 而不是 foo a gt b foo x bar x where ba
  • Haskell 项目可以使用 cmake 吗?

    我正在计划一个用 Haskell 编写的项目 也许也有一些部分是用 C 编写的 对于构建系统 我决定不选择 Haskell 程序 cabal 的常见选择 主要是因为我想了解其他语言的构建程序是如何工作的 我听说过 CMake 我认为这是一个
  • 使用 Reader Monad 进行依赖注入

    我最近看到了谈话极其简单的依赖注入 http www youtube com watch v ZasXwtTRkio and 无需体操的依赖注入 http vimeo com 44502327关于 Monads 的 DI 并留下了深刻的印象
  • Python 3:将元组转换为字符串

    我有以下代码 var one var two var three 1 var one string one var 1 我需要对其执行以下操作 var four string two var one 但是 这会返回以下错误 TypeErro
  • Haskell:对 Num 类型类的使用感到困惑

    我很困惑为什么这有效 f Num a gt a gt a f x x 42 但这并没有 g Num a gt a gt a g x x 4 2 我本来就明白Num包含实现运算符的所有类型 因此 如果42 is an Int and 4 2
  • 如何使用foldr为列表创建显示实例?

    我想为我的数据类型 我的列表 编写自己的显示实例 到目前为止 我的方法是有效的 但我总是在末尾有一个逗号 我已经尝试用最后一个元素启动折叠并将其从列表中删除 但它很麻烦而且不起作用 有没有更简单的方法来获得正确的解决方案 实际 1 2 3
  • Haskell 点运算符

    我尝试在 Haskell 中开发一个简单的平均函数 这似乎有效 lst 1 3 x fromIntegral sum lst y fromIntegral length lst z x y 但是为什么下面的版本不行呢 lst 1 3 x f
  • 将元组列表转换为字符串 Python

    例如 我用 python 编写了一个返回列表的函数 1 1 2 2 3 3 但我希望输出为字符串 这样我就可以用另一个字符替换逗号 这样输出就是 1 1 2 2 3 3 有什么简单的方法可以解决这个问题吗 感谢您提前提供任何提示 这看起来像
  • Scala 函数定义参数列表中不同的括号样式

    Scala 中以下两个函数定义有什么区别 1 def sum f Int gt Int a Int b Int Int code 2 def sum f Int gt Int a Int b Int Int code SBT 的控制台 RE
  • 如何让 do 块提前返回?

    我正在尝试使用 Haskell 抓取网页并将结果编译到一个对象中 如果出于某种原因 我无法从页面获取所有项目 我想停止尝试处理页面并提前返回 例如 scrapePage String gt IO scrapePage url do doc
  • 泛化 R %in% 运算符以匹配元组

    前几天我花了一段时间寻找一种方法来检查行向量是否包含在 R 中的某些行向量集中 基本上 我想概括 in 运算符来匹配元组而不是向量中的每个条目 例如 我想要 row vec c A 3 row vec 1 A 3 data set rbin
  • 有没有好的 Clojure 基准测试?

    Edit Clojure 基准测试已达到基准游戏 http benchmarksgame alioth debian org u64q clojure html 我已经制作了这个问题社区维基并邀请其他人保持更新 有人知道 Clojure 性
  • Haskell 中的所有内容都存储在 thunk 中吗,甚至是简单的值?

    以下值 表达式 函数的 thunk 在 Haskell 堆中是什么样子的 val 5 is val a pointer to a box containing 5 add x y x y result add 2 val main prin
  • Haskell 中多核编程的现状如何?

    Haskell 中多核编程的现状如何 现在有哪些项目 工具和库可用 有哪些经验报道 2009年至2012年期间 发生了以下事件 2012 从 2012 年开始 并行 Haskell 状态更新开始出现在并行 Haskell 摘要 http w

随机推荐