Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
lisp反引号和拼接的Haskell模拟_Haskell_Lisp_Template Haskell_Quasiquotes - Fatal编程技术网

lisp反引号和拼接的Haskell模拟

lisp反引号和拼接的Haskell模拟,haskell,lisp,template-haskell,quasiquotes,Haskell,Lisp,Template Haskell,Quasiquotes,在某些Lisp(例如)中,有一个称为反向引用的功能 它允许在对某些元素进行求值或拼接时构造列表。例如: (12(3(+45))) ⇒ (1 2 (3 (+ 4 5))) ; 刚报价的未估价清单 `(1 2 (3 ,(+ 4 5))) ⇒ (1 2 (3 9)) ; (+4.5)已经过评估 `(一,二)(名单三(四,五)) ⇒ (1 2 3 9) ; (3.9)已拼接到列表中 我猜,在Haskell中,回溯的某些子集可能如下所示: [backquote| 1, 2, @$

在某些Lisp(例如)中,有一个称为反向引用的功能

它允许在对某些元素进行求值或拼接时构造列表。例如:

(12(3(+45))) ⇒ (1 2 (3 (+ 4 5))) ; 刚报价的未估价清单 `(1 2 (3 ,(+ 4 5))) ⇒ (1 2 (3 9)) ; (+4.5)已经过评估 `(一,二)(名单三(四,五)) ⇒ (1 2 3 9) ; (3.9)已拼接到列表中 我猜,在Haskell中,回溯的某些子集可能如下所示:

 [backquote| 1, 2, @$(replicate 2 3), 2 + 2 |]
 ⇒ [1, 2, 3, 3, 4]

我想知道,这样拼接到列表中是否可行,是否已经实施。

评论中的讨论似乎有点偏离了轨道。无论如何,我对此有不同的看法,所以让我给出一个答案

我想说Haskell已经有了一个类似于反向引用的特性,您可能已经在自己的Haskell编程中广泛地使用了它,但没有意识到这一点

您已经在Lisp列表和Haskell列表之间绘制了一个平行关系,但在Lisp中,S表达式(即“与原子的配对”,尤其是与原子符号的配对)是一种灵活且普遍存在的数据结构,不仅用于表示Lisp代码,而且还作为go-to表示,这至少是任何复杂代码的首要考虑因素,结构化数据。因此,大多数Lisp程序花费大量时间生成和操作这些结构,因此S表达式“文字”在Lisp代码中很常见。而且,S表达式“几乎是文字”,其中需要计算一些子表达式,使用反向引用机制编写比使用诸如
cons
list
append
等函数尝试使用较小的文字和计算片段构建表达式更方便

与Haskell形成对比的是,Haskell列表在Haskell代码中当然很流行,是表示同构序列的一种常用结构,但它们只提供了S表达式灵活性的一小部分。相反,Haskell中相应的泛在数据结构是代数数据类型(ADT)

就像Lisp的S表达式一样,Haskell程序花费大量时间生成和操作ADT,Haskell还有一个方便的ADT文本和“几乎文本”语法。它们被统一到一个“函数应用程序”语法中,其文字和计算部分通过使用构造函数(标识符以大写字母开头或中缀运算符以冒号开头)与非构造函数(标识符以小写字母开头或中缀运算符以冒号开头)进行区分。当然,对于某些构造函数(列表和元组),还有一些额外的语法

例如,比较Lisp和Haskell中的以下反引号表达式:

;; Lisp
(setq baz `(node ,id
                 (node ,(+ id 1) ,left-tree leaf)
                 (node ,(+ id 2) leaf ,right-tree)))
-- Haskell
baz = Node id (Node (id + 1) left_tree Leaf) (Node (id + 2) Leaf right_tree)
在Haskell版本的“几乎是文字”中,
节点
构造函数表示引用的部分;
左树
右树
+
中缀表达式表示已计算的部分,它们可以通过构造函数和非构造函数的常用规则进行语法区分


当然,与此完全不同的是,有一个模板Haskell机制,它在编译时直接处理Haskell代码片段。虽然该代码表示为ADT,原则上可以使用与其他ADT相同的“几乎文字”语法编写,但所讨论的ADT相当麻烦,与底层Haskell代码完全不同。因此,模板Haskell提供了一种更为经典的反向引用语法。

注释不用于扩展讨论;这段对话已经结束了。谢谢你的精彩回答,但是你完全把注意力放在了回溯的半评估功能上,这在Haskell中有点微不足道。然而,最有趣的部分是拼接。我在讨论中提到了它,但我想我会编辑这个问题来澄清。如果这是反引用,那么没有反引用的Lisp也有反引用。看<代码>(生成节点id(生成节点(+id 1)左树的叶)(生成节点(+id 2)…)>节点和叶构造函数表示引用的部分。。然而,这不是一个象征。这看起来像是漫长而痛苦的“评论中的讨论”的开始,所以请考虑这个澄清的评论,这是我对这个问题的绝对的最后一句话。IMHO,Haskell构造函数和函数是完全不同的对象,尽管它们在表面上有一些相似之处,这就是我要说的。构造函数更像(引用的)Lisp符号,而不是Lisp函数——将其视为“自引用”符号。因此,在Haskell中,你可以重新引用“免费”,因为在自引用符号和函数之间存在语法上的区别。