Pact 接口如何提供类似于 Haskell 类型类的抽象?



Pact文档提到Pact中的接口允许类似于Haskell的类型类的抽象:

当一个模块

发出一个实现时,那么该模块被称为"实现"所述接口,并且必须提供一个实现。这允许抽象类似于Java的接口,Scala的特征,Haskell的类型类或OCaML的签名。可以在给定模块中实现多个接口,从而允许行为的表达分层。

我知道你可以编写一个接口(这对应于在 Haskell 中声明一个class),然后你可以为一个或多个模块实现接口(这与 Haskell 中的instance相对应)。例如:

-- This corresponds with declaring an interface
class Show a where
show :: a -> String
-- This corresponds with implementing an interface
instance Show Bool where
show True = "True"
show False = "False"

但是,Haskell类型类的最大价值在于您可以对其进行抽象。您可以编写一个函数,只要它是Show的实例,它就接受任何值:

myFunction :: (Show a) => a -> ...
myFunction = ...

契约中的相应概念是什么?有没有办法接受任何模块作为依赖项,只要它实现了接口?如果不是,这如何"在类似于Haskell的类型类的意义上"打开抽象?

我认为您的问题可能是将类型类与类型变量和通用量化混为一谈。类型类为您提供了一个通用接口,例如show,可用于支持它们的任何类型(或在本例中为模块)。通用量化允许您编写适用于任何Show实例的通用算法。

《公约》提供了前者,但没有提供后者。主要实用程序是为您的模块提供一个模板来工作,任何知道该接口的人都可以使用您的模块。这使得"交换实现"成为可能,但并没有为"通用算法"打开大门。为此,我们需要某种方式来表达"对于所有实现接口的模块"......

更新:根据Stuart Popejoy的评论,这种抽象确实可以使用modrefs来实现。下面是一个模块的示例,该模块在任何实现特定接口的模块上实现泛型方法:

(interface iface
(defun op:integer (arg:string)))
(module impl1 G
(defcap G () true)
(implements iface)
(defun op:integer (arg:string) (length arg)))
(module impl2 G
(defcap G () true)
(implements iface)
(defun op:integer (arg:string) -1))
(module app G
(defcap G () true)
(defun go:integer (m:module{iface} arg:string)
(m::op arg)))
(expect "impl1"  5 (app.go impl1 "hello"))
(expect "impl2" -1 (app.go impl2 "hello"))

最新更新