Haskell元组构造函数(GHC)和语言及其实现之间的分离 [英] Haskell tuple constructor (GHC) and the separation between a language and its implementation

查看:164
本文介绍了Haskell元组构造函数(GHC)和语言及其实现之间的分离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 (x,y)



$ p


$ b $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ (,)xy

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

 (,)x((,)yz)

给我

 (x,(y,z))

这不是我正在寻找的。一时兴起,我试过了

 (,,)xyz 

它的工作原理正是我想要的:

 (x ,y,z)

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

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

这种行为令人惊讶,导致我的实际问题:是否可以在我自己的功能中模拟的东西?或者它只是元组运算符的GHC特有的功能?
我认为这是后者,因为我已经阅读了haskell98规范和iirc,它说实现只需要为多达15个项目定义元组运算符。鉴于GHC已经走了整个猪圈,并让你做到了任意限制。

那么,是否有可能在haskell中定义这个操作符/函数族实现本身,只使用类型系统和现有的语言特性(声明,类型签名,函数定义等)?如果是这样,怎么样?或者是不可能的,你必须改为查看编译器来找到这个函数集合的支持框架?



这导致了一个更普遍的问题:多少Haskell支持Haskell本身,通过类型和函数定义,声明等;以及编译器/实现支持多少? (我知道GHC是用Haskell编写的,并没有回答这个问题)。

就是说,如果你要放弃标准库(包括前奏)从原始的Haskell中完成所有工作;是否有可能建立一个完整的实现,它具有GHC的所有功能,只使用最少的一组功能?为了使用Haskell构建一个haskell实现,你需要什么样的语言特性?我可以放弃前奏,然后完全从GHC内手动重建 吗?如果你放弃前奏并且永远不要输入任何东西,那么剩下什么让你去工作?



看起来我似乎在问一百万个问题,但他们都试图用不同的措词问同样的问题。给它最好的拍摄!

解决方案

唉,元组中没有魔法。 这是GHC使用的实施,并给你一些关于最新定义的来源的信息:

  data(,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,)abcdefghijklmnopqrstu vwxyz 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__ 
=( ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,, ,, ab ab ab ab ab ab ab ab ab ab ab

...是的。


那么,是否有可能在haskell实现本身中定义这个操作符/函数族,除了类型系统和现有的语言特性s(声明,类型签名,函数定义等)?如果是这样,怎么样?或者是不可能的,你不得不看看编译器来找到这个函数集合的支持框架吗?


不,有没有办法以通用的方式定义这样的元组。常见的模式纯粹是句法,在类型系统或其他方面可以递归地完成任何事情。你当然可以使用Template Haskell生成这样的定义,但是你仍然可以通过字符串操作单独生成每个单独的名称,而不是使用任何共享结构。



还有一个问题是,元组语法是内置的,而不是可以模仿的东西,但这是一个单独的问题。你可能想象的类型如下:

  data Tuple2 ab = Tuple2 ab 
data Tuple3 abc = Tuple3 abc

...等等,它们没有使用特殊的语法,但仍然不能基于上述原因。
$ b


这导致了一个更普遍的问题:Haskell本身支持多少Haskell,通过类型和函数定义,声明等;以及编译器/实现支持多少? (我知道GHC是用Haskell编写的,并没有回答这个问题)
几乎所有的都是在Haskell中定义的。某些事情有特殊的语法,你不能模仿,但在大多数情况下,只有在编译器特别注意某些定义的情况下才会扩展。否则,这个


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

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


也就是说,如果你放弃标准库(包括前奏)并且从原始的Haskell中完成所有事情;是否有可能建立一个完整的实现,它具有GHC的所有功能,只使用最少的一组功能?为了使用Haskell构建一个haskell实现,你需要什么样的语言特性?我能否放弃前奏,然后从GHC内手动完成重建?如果你放弃了前奏,并且从不输入任何东西,剩下什么可以让你使用?


你可能会觉得它很有启发性关于GHC的 NoImplicitPrelude和RebindableSyntax 扩展程序,它们可让您,除其他外,改变用于解释 do 符号的定义,数字文字是如何处理的,以及 if if else 语法,等等。



只要说很少,就不能重新实现。大多数事情由于语法的原因而不是特殊的,并且可以用等价的东西来替代(比如上面的列表和元组)。

最后有一个限制一系列具有 特殊行为的事物 - IO 类型是一个明显的例子 - 您根本无法替换它们,因为它们'直接挂载到运行时系统中您无法替换的部分。


Haskell blew my mind yet again when I realised that

(x,y)

Is just syntactic sugar for

(,) x y

Naturally I wanted to extend this to larger tuples. But

(,) x ((,) y z)

Gave me

(x,(y,z))

Which was not what I was looking for. On a whim, I tried

(,,) x y z

And it worked, giving exactly what I wanted:

(x,y,z)

This raised the question: How far can you take it? Much to my astonishment, there seemed to be no limit. All of the below are valid operators:

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

This behaviour is amazing and leads to my actual question: Is it something which can be emulated in my own functions? Or is it just a GHC-specific feature of the tuple operator? I'm thinking it's the latter as I've read the haskell98 specification and iirc it says that implementations only have to define the tuple operator for up to 15 items. Whereas GHC has gone the whole hog and let you do it up to arbitrary limits.

So, would it be possible to define this family of operators/functions from within the haskell implementation itself, using nothing but the type system and existing language features (declarations, type signatures, function definitions etc.)? And if so, how? Or is it impossible and you have to instead look into the compiler to find the supporting framework for this collection of functions?

This leads to an even more general question: How much of Haskell is supported by Haskell itself, through type and function definitions, declarations etc; and how much is supported by the compiler/implementation? (I am aware that GHC was written in Haskell, that doesn't answer the question)

That is, if you were to abandon the standard libraries (including the prelude) and do everything from the ground up in raw Haskell; would it be possible to build a complete implementation that has all the features of GHC, using only that minimal set of features? What are the mimimum set of language features that you need in order to build a haskell implementation using Haskell? Would I be able to abandon the prelude and then completely rebuild it manually from within GHC? If you abandon the prelude and never import anything, what is left over for you to work with?

It may seem like I'm asking a million questions, but they're really all trying to ask the same thing with different wording. Give it your best shot SO!

解决方案

Alas, there is no magic in the tuples. Here's the implementation GHC uses, and to give you some idea of what's going on here's the source for the last definition:

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.

So, would it be possible to define this family of operators/functions from within the haskell implementation itself, using nothing but the type system and existing language features (declarations, type signatures, function definitions etc.)? And if so, how? Or is it impossible and you have to instead look into the compiler to find the supporting framework for this collection of functions?

No, there's no way to define the tuples like that in a generic way. The common pattern is purely syntactic, nothing that can be done recursively in the type system or otherwise. You could generate such definitions using Template Haskell, certainly, but you'd still be generating each individually with string manipulation to create the name, not using any sort of shared structure.

There's also the matter that tuple syntax is built-in and not something that can be imitated, but that's a separate issue. You might imagine types like:

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

...etc., which don't use special syntax but still can't be defined generically for the reasons above.

This leads to an even more general question: How much of Haskell is supported by Haskell itself, through type and function definitions, declarations etc; and how much is supported by the compiler/implementation? (I am aware that GHC was written in Haskell, that doesn't answer the question)

Almost all of it is defined in Haskell. Certain things have special syntax you can't imitate, but in most cases that only extends as far as the compiler giving special attention to certain definitions. Otherwise, there's no difference between this:

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

...and any equivalent type you define yourself.

That is, if you were to abandon the standard libraries (including the prelude) and do everything from the ground up in raw Haskell; would it be possible to build a complete implementation that has all the features of GHC, using only that minimal set of features? What are the mimimum set of language features that you need in order to build a haskell implementation using Haskell? Would I be able to abandon the prelude and then completely rebuild it manually from within GHC? If you abandon the prelude and never import anything, what is left over for you to work with?

You may find it enlightening to read about GHC's NoImplicitPrelude and RebindableSyntax extensions, which let you, among other things, change the definitions used to interpret do notation, how numeric literals are handled, what the if then else syntax does, etc.

Suffice it to say that very, very little can't be reimplemented. Most things that can't are only special due to syntax, and could be replaced with equivalent stuff (like lists and tuples, above).

In the end there's a limited set of things that have very special behavior--the IO type being an obvious example--that you can't replace at all, because they're hooked directly into something in the runtime system that you can't replace.

这篇关于Haskell元组构造函数(GHC)和语言及其实现之间的分离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆