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

时间:2011-08-17 00:19:17

标签: haskell functional-programming tuples ghc comma

当我意识到

时,Haskell又一次震惊了我的脑海
(x,y)

只是

的语法糖
(,) x y

当然我想把它扩展到更大的元组。但

(,) x ((,) y z)

给我

(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实现,您需要哪些最小的语言功能集?我是否能够放弃前奏,然后完全从GHC中手动重建 ?如果你放弃了前奏而从不导入任何东西,你还有什么可以继续使用?

看起来好像我问了一百万个问题,但他们真的都试图用不同的措辞问同样的问题。给你最好的拍摄SO!

1 个答案:

答案 0 :(得分:38)

唉,元组中没有魔法。 Here's the implementation GHC uses,并告诉你这里发生了什么是最后一个定义的来源:

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__

...是

  

那么,是否可以在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

之间没有区别
data [] a = [] | a : [a]

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

  

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

您可能会发现阅读有关GHC的NoImplicitPrelude and RebindableSyntax扩展的启发,这些扩展可以让您更改用于解释do符号的定义,如何处理数字文字,{{{ 1}}语法等等。

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

最后,有一组有限的东西具有非常特殊行为 - if then else类型是一个明显的例子 - 你完全无法取代,因为它们'直接挂在运行时系统中你无法替换的东西。