【发布时间】:2012-12-16 08:01:37
【问题描述】:
我试图理解一种逻辑编程语言(在我的例子中是 Prolog)和 Haskell 的类型系统之间的关系。
我知道根据关系使用统一和变量来查找值(或类型,在 Haskell 的类型系统中)。为了更好地理解它们之间的异同,我尝试在 Haskell 的类型级别重写一些简单的 prolog 程序,但我在某些部分遇到了问题。
首先,我重写了这个简单的 prolog 程序:
numeral(0).
numeral(succ(X)) :- numeral(X).
add(0,Y,Y).
add(succ(X),Y,succ(Z)) :- add(X,Y,Z).
作为:
class Numeral a where
numeral :: a
numeral = u
data Zero
data Succ a
instance Numeral Zero
instance (Numeral a) => Numeral (Succ a)
class (Numeral a, Numeral b, Numeral c) => Add a b c | b c -> a where
add :: b -> c -> a
add = u
instance (Numeral a) => Add a Zero a
instance (Add x y z) => Add (Succ x) (Succ y) z
它工作正常,但我无法用这个 Prolog 扩展它:
greater_than(succ(_),0).
greater_than(succ(X),succ(Y)) :- greater_than(X,Y).
我尝试的是这样的:
class Boolean a
data BTrue
data BFalse
instance Boolean BTrue
instance Boolean BFalse
class (Numeral a, Numeral b, Boolean r) => Greaterthan a b r | a b -> r where
greaterthan :: a -> b -> r
greaterthan = u
instance Greaterthan Zero Zero BFalse
instance (Numeral a) => Greaterthan (Succ a) Zero BTrue
instance (Numeral a) => Greaterthan Zero (Succ a) BFalse
instance (Greaterthan a b BTrue) => Greaterthan (Succ a) (Succ b) BTrue
instance (Greaterthan a b BFalse) => Greaterthan (Succ a) (Succ b) BFalse
此代码的问题是最后两个实例导致了资金冲突。我可以理解为什么,但在我看来这应该不是问题,因为它们的保护部分(或其他任何名称,我的意思是 (Greaterthan a b c) => 部分)是不同的,所以 as 和 b最后两个实例声明中的 s 实际上是不同的值,没有冲突。
我尝试重写的另一个程序是:
child(anne,bridget).
child(bridget,caroline).
child(caroline,donna).
child(donna,emily).
descend(X,Y) :- child(X,Y).
descend(X,Y) :- child(X,Z),
descend(Z,Y).
(顺便说一句,示例来自Learn Prolog Now book)
data Anne
data Bridget
data Caroline
data Donna
data Emily
class Child a b | a -> b where
child :: a -> b
child = u
instance Child Anne Bridget
instance Child Bridget Caroline
instance Child Caroline Donna
instance Child Donna Emily
class Descend a b | b -> a where
descend :: b -> a
descend = u
instance (Child a b) => Descend a b
instance (Child a c, Descend c b) => Descend a b
最后一行出现“重复实例”错误。我认为这是一个类似的问题,即使我有不同的防护部件,我也会遇到错误,因为身体部位(我的意思是 Descend a b 部件)是相同的。
因此,如果可能的话,我正在寻找将 Prolog 程序移植到 Haskell 类型级别的方法。任何帮助将不胜感激。
编辑:
Ed'ka 的解决方案有效,但方式完全不同。我仍在尝试了解我们何时可以在类型系统中运行 Prolog 程序,何时/为什么我们需要编写不同的算法以使其工作(如在 Ed'ka 的解决方案中),以及何时/为什么没有办法在 Haskell 的类型系统中实现一个程序。
也许我可以在阅读“Fun With Functional Dependencies”之后找到一些关于此的提示。
【问题讨论】:
-
如果您还没有完成一些简单的“类型级序言”,请参阅 Thomas Hallgren 的函数依赖乐趣cse.chalmers.se/~hallgren/Papers/wm01.html。最后两行总是会得到重复的实例,因为它们是重复的 - GHC 并不关心约束是否不同。
-
您可能对Mercury 感兴趣:Mercury 是一种面向实际应用的函数式逻辑编程语言。 ... Mercury 是一种纯粹的声明性逻辑语言。它与 Prolog 和 Haskell 都有关。它具有强大的静态多态类型系统以及强大的模式和确定性系统。
-
您可能可以从
-XTypeFamilies获得更多相关类型同义词,但我不确定多少。有趣的问题 -
@stephentetley 感谢您的链接,但后记下载链接不起作用,您知道其他镜像吗?
-
@sinan - 试试 Citeseer citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.7806
标签: haskell prolog type-systems logic-programming