85

我在有关 haskell 和函数式编程的博客(特别是sigfpe 的博客)中阅读了很多这个术语,但我不知道它的含义。大多数时候我都不知道它,但如果我知道的话,我可能会更好地理解这些文本。谷歌没有帮助我。我迷失在技术方面。

此外,世界的非技术意义(“将抽象具体化”)并不能帮助我理解在代码中具体化某些东西实际上意味着什么。

我对计算机科学概念有点慢,所以带有代码的实际示例会很好。:P

4

6 回答 6

47

所以我读了这篇文章,这几乎就是它的意思:采用抽象概念并将其具体化。或者,有一个代表抽象概念的代理。例如,在 Lisp 中,当您使用 lambda 时,过程抽象和应用程序的概念就被具体化了。

具体化本身是一个广泛的概念,不仅适用于函数式编程语言。

例如,在 Java 中,有一些类型在运行时可用。这些是可具体化的类型。意思是,在运行时存在类型的抽象概念的具体表示。相反,有不可具体化的类型。这在 Java 中使用泛型时尤其明显。在 Java 中,泛型受到类型擦除的影响,因此泛型类型信息在运行时不可用(除非参数化类型使用无界通配符)。

另一个示例是当您尝试对概念进行建模时。例如,假设您有一个Group类和一个User类。现在有一些抽象的概念来描述两者之间的关系。User例如, a 是 a的成员的抽象概念Group。为了使这种关系具体化,您将编写一个名为的方法isMemberOf来说明 a 是否User是 a 的成员Group。所以你在这里所做的是你已经具体化(使真实/明确/具体)组成员身份的抽象概念

另一个很好的例子是一个数据库,其中对象之间存在父子关系。您可以用树的抽象概念来描述这种关系。现在假设您有一个从数据库中获取这些数据并构造一个实际 Tree对象的函数/方法。您现在所做的是将父子树状关系的抽象概念具体化为实际对象 Tree

回到一般的函数式语言,也许具体化的最好例子是创建 Lisp 编程语言本身。Lisp 是一个完全抽象的理论结构(基本上只是计算机语言的数学符号)。直到 Lisp 的eval功能由 Steve Russel 在 IBM 704 上实际实现之前,它一直保持这种状态:

根据 Paul Graham 在 Hackers & Painters 中的报道,p。185,McCarthy 说:“Steve Russell 说,看,我为什么不对这个 eval 进行编程……我对他说,嗬,嗬,你把理论和实践混为一谈了,这个 eval 是用来阅读的,不是用于计算。但他继续做了。也就是说,他将我论文中的 eval 编译成 IBM 704 机器代码,修复了 bug ,然后将其宣传为 Lisp 解释器,它确实是。所以那时 Lisp基本上就是今天的样子……”

所以 Lisp 从一个抽象的概念被具体化为一种实际的编程语言。  

于 2011-03-15T17:18:06.950 回答
28

物化

物化是实例化的一种形式。当你具体化一个概念时,你把一些抽象的东西具体化,就像你提供的字典定义一样。

您可能会选择将类型具体化为包含可能类型的一些抽象语法树的术语。

你可以通过为某种语言提出一个通用的实现来具体化一个设计模式。例如,像

template<typename T> class Singleton {
    public:
        static T& Instance() {
            static T me;
            return me;
        }

    protected:
       virtual ~Singleton() {};
       Singleton() {};
}

将单例设计模式具体化为 C++ 中的模板。

您可以将 Hoare 的快速排序理念具体化为您选择的编程语言的实现。在这方面,我花了很多时间将范畴论中的概念具体化为 Haskell 代码。

您可以将一种语言具体化为该语言的解释器。Larry Wall 的Perl语言思想被具体化为 perl 解释器。

data-reifyVacuum包将术语具体化为图形,表示它在内存中如何通过共享进行结构化。

反射

物化的另一面是反射,它采用具体的东西,并产生抽象,通常是通过忘记一些细节。也许您想这样做是因为抽象更简单,或者以某种方式抓住了您所谈论内容的本质。

Java、C# 等中的类型系统反射采用编程语言中的具体类,并为您提供类的抽象结构,让您可以访问类提供的成员列表。在这里,我们采用类型的具体概念,并从中生成一个描述其结构的抽象术语,同时丢弃任何特定值。

就像如何将编程语言具体化为实现一样,有时您可能会朝相反的方向发展。尽管这通常被认为是一个坏主意,但您可能会采用一个实现并尝试从其行为的理想属性中反映语言规范。TeX首先由 Knuth 实现,没有规范。TeX 的任何规范都反映在 Knuth 的实现中。

(更正式地说,如果您将反射视为一个健忘的函子,它将您从具体领域带到抽象领域,那么理想情况下,具体化是与反射相伴的。)

我维护的反射包提供了一个 reify 方法,它接受一个术语并产生一个表示它的类型,然后是一个反射方法,可以让您生成一个新术语。这里的“具体”域是类型系统,而抽象域是术语。

于 2011-03-15T18:04:28.517 回答
21

来自Haskell 维基

“物化”某物就是把抽象的东西当作物质的东西。一个典型的例子是古人将抽象概念(如“胜利”)转化为神灵(如希腊胜利女神耐克)的方式。

具体化类型是表示类型的值。使用具体类型而不是真实类型意味着您可以对它们进行任何您可以对值进行的操作。

于 2011-03-15T17:08:52.027 回答
15

我能想到的一个用途(我相信还有其他用途!)是将一个类变成字典。让我们上课(暂时Eq忘记操作员):/=

class Eq a where
    (==) :: a -> a -> Bool

如果我们具体化这个类,它变成:

data EqDict a = EqDict (a -> a -> Bool)

可以建造,检查等。Eq另外值得注意的是,每种类型只能有一个实例,但可以有多个EqDict值。但是实例的自动构造(例如,当您为元素获取列表时获得相等)不起作用。您必须自己构建EqDict [a]价值。

物化过程就像这样简单(对于这种情况):

reify :: Eq a => EqDict a
reify = EqDict (==)

使用Eq该类的函数可以转换如下内容:

-- silly example, doesn't really do anything
findMatches :: Eq a => a -> [a] -> [a]
findMatches x ys = [ y | y <- ys, x == y ]

-- version using EqDict
findMatchesDict :: EqDict a -> a -> [a] -> [a]
findMatchesDict (EqDict f) x ys = [ y | y <- ys, f x y ]

如果您打开 EqDict 并仅传递一个a -> a -> Bool,您将获得..By函数,likeData.List.nubBy和 friends - 一个类似的技巧Ord导致Data.List.sortBy.

于 2011-03-15T17:16:59.087 回答
9

即使只是在 Haskell 的上下文中,该术语的使用也非常广泛。Andy Gill 的 reify 包允许您采用递归结构并将它们转换为显式图。Sigpfe 关于延续的帖子描述了将“其余计算”的概念具体化为您可以传递的值。模板 Haskell 有一个 reify 函数(通常在编译时与 TH 代码一起执行),当给定 Haskell 值的名称时,它会返回可用的信息(声明的位置、类型等)。

所有这些案例有什么共同点?他们正在谈论获取一些我们可以推理和知道但我们不能直接以编程方式操作的东西,并将其转化为我们可以像其他任何东西一样命名和传递的实际第一类值。这通常是人们在使用这个词时想要表达的意图。

于 2011-03-15T17:46:55.500 回答
3

我知道 RDF 中有具体化的概念。正如Tim Bernes-Lee 所说

在这种情况下,具体化意味着使用该语言以一种语言表达某物,从而使其可以被该语言处理。

我想这有点像反思或内省。我希望你在这里得到一些好的答案!

于 2011-03-15T17:13:14.920 回答