Prolog与Haskell

这不是一个家庭作业问题,而是考试学习指导问题。 Prolog与Haskell中的模式匹配有什么区别?

我已经做了一些研究,阅读其背后的理论并不能让我在两者之间有一个明确的理解。 我在Prolog中读到,模式匹配是不同的,因为它具有统一变量的能力,从而能够通过分辨率推断并吐出可能的答案

eg ?- [a,b] = [a,X]
   X = b

现在我不确定如何在Haskell中显示模式匹配。 我知道在Prolog中显示的同一个查询在Haskell中不起作用,因为Haskell不能像Prolog一样统一。 我记得在Haskell中得到相同答案的地方,你必须明确告诉它通过守卫。

我知道我非常接近理解它,但我需要有人为我打破巴尼的风格,所以我可以充分理解它并将其解释为一个12岁的孩子。 这一直困扰我很长一段时间,我似乎无法找到一个坚实的解释。

顺便说一下,上面显示的例子只是为了向你们展示我迄今为止学到的东西,并且我实际上试图找到答案。 我的主要问题并不涉及上述例子,而是对两者之间的区别有一个完整的理解。


Prolog模式匹配基于统一,特别是Martelli-Montanari算法(默认情况下减去发生检查)。 该算法匹配相同位置的值,将一侧的变量绑定到另一侧的相应位置的值。 这种模式匹配可以同时工作,因此在Prolog中可以使用参数作为输入和输出。 一个简单的例子, length/2谓词。 我们可以使用它来(评论解释查询):

?- length([],0).      % is the length of empty list zero?
?- length([a,b,c],X). % what's the length of list consisting of a,b and c?
?- length(L,5).       % give me all lists that have length of 5

Haskell模式匹配是一种单向匹配,用于将变量绑定到给定值的不同部分。 一旦绑定,它会执行相应的操作(右侧)。 例如,在函数调用中,模式匹配可能决定调用哪个函数。 例如:

sum []     = 0
sum (x:xs) = x + sum xs

第一个和结合空列表,而第二个结合至少一个元素的列表。 基于此,给定sum <a list> ,结果可以是0x + sum xs具体取决于sum (x:xs) sum <a list>是否匹配sum []sum (x:xs)


与Haskell和Prolog的统一一样,模式匹配之间的差异源于两种语言中根本不同的变量。

在Haskell中,变量保存值。 具体的价值。 这样的价值可能还没有被计算出来,甚至可能是⊥,但否则它就是一个具体价值。 在Haskell中,你不能接受一个变量,只能首先声明它的一些属性值。

所以模式匹配总是意味着一个具体的值与包含一些变量的模式匹配。 这种匹配的结果要么是失败,要么是变量与具体价值的约束。 在Haskell中,这被进一步限制,以避免一般比较的需要,这意味着类Eq是为匹配的术语定义的。

然而,在Prolog中,变量可能指的是一组可能的解决方案。 变量可能发生在任何地方 - 也可能在其他值之间。 统一现在可以确保规定的平等仍然成立,并且结果得到最佳表示,即计算最一般的统一者。


| ?- length(L,5).                      
L = [_,_,_,_,_]
| ?- length(L,5), maplist(=(E),L).
L = [E,E,E,E,E]

所以Prolog在这里没有回答具体的值,如L = [1,1,1,1,1]L = [[],[],[],[],[]]但给出了最一般的统一答案包含所有这些具体的价值观。


没有人提到以下非常重要的区别。 在Prolog中,模式匹配会针对谓词的每个子句进行尝试,即使之前的某个匹配已成功(除非停止缩短)。 但是在Haskell中,条款匹配只会在第一次成功之前尝试。 没有其他的选择被尝试(除非比赛被一名后卫拒绝)。

Prolog的模式匹配在最普遍的意义上建立了一个等式约束(详见@false的回答)。 共享是明确的A=B, A=5设置B=5 。 这是可能的,因为Prolog的logvar可以处于尚未设置的状态(即未被实例化)。 这使搭便车变得简单(实际上是一种基本的编程技术,即差异列表)。

在Haskell中,任何变量都只能在语法级别定义一次。 在Prolog中,logvar只设置一次 (无回溯),但允许指向不完整的结构(数据),其中空洞由其他尚未实例化的logvars表示,可以在以后的任何时间点设置。

在Haskell中,用守护递归定义的给定结构按访问要求逐步充实。 在Prolog中,在初始实例化一个变量后,任何后续的统一变成验证术语的兼容性,并可能进一步实现 (可能是部分又一次) 实例化 (明确“填补”这些洞)。

链接地址: http://www.djcxy.com/p/80775.html

上一篇: Prolog vs. Haskell

下一篇: What language to learn after Haskell?