Raf*_*ini 77 haskell functional-programming terminology metaprogramming reification
我在关于haskell和函数式编程的博客中经常阅读这个术语(特别是在sigfpe的博客中),但我不清楚这是什么意思.我大部分时间都不知道,但如果我知道,我可能会更好地理解文本.谷歌没有帮助我.我迷失在技术方面.
此外,世界的非技术含义("改变抽象具体")并没有帮助我理解在代码中实现某些东西的实际意义.
我对计算机科学概念有点慢,所以使用代码的实际例子会很好.:P
Viv*_*ath 37
所以我读到了这个,它几乎意味着什么:采用一个抽象概念并使其具体化.或者,有一个代表抽象概念的代理.例如,在Lisp中,当使用lambdas时,程序抽象和应用程序的概念就会被实现.
具体化是一个广泛的概念,不仅适用于函数式编程语言.
例如,在Java中,有一些类型在运行时可用.这些是可再生的类型.意思是,在运行时期间,存在类型的抽象概念的具体表示.相反,存在不可再生类型.在Java中使用泛型时尤其明显.在Java中,泛型需要进行类型擦除,因此在运行时期间不能使用泛型类型信息(除非参数化类型使用无界域通配符).
另一个例子是当你尝试建模概念时.例如,假设您有一个Group
类和一个User
类.现在有一些描述两者之间关系的抽象概念.例如,a的抽象概念是a User
的成员Group
.为了使这种关系具体化,你会写一个名为a的方法isMemberOf
,说明a是否User
是a的成员Group
.所以你在这里所做的就是你已经具体化(制作了真实的/明确的/具体的)群体成员资格的抽象概念.
另一个很好的例子是一个数据库,你在这个数据库中有对象的父子关系.您可以在树的抽象概念中描述这种关系.现在假设你有一个函数/方法从数据库中获取这些数据并构造一个实际的 Tree
对象.什么你现在所做的是物化父子树状关系的抽象的概念变成一个实际的 Tree
对象.
回到一般的函数式语言,或许最好的具体化例子就是创建Lisp编程语言本身.Lisp是一个完全抽象的理论构造(基本上只是计算机语言的数学符号).它一直保持这种状态,直到Lisp的eval
功能实际上由Steve Russel在IBM 704上实现:
根据Paul Graham在Hackers&Painters中报道的内容,p.185,麦卡锡说:"史蒂夫罗素说,看,为什么我不编程这个评估...,我告诉他,你好,你是理论与实践混淆,这个评估是为了阅读,而不是但是他继续前进并做到了.也就是说,他将我的论文中的eval编译成IBM 704机器码,修复了bug,然后将其作为Lisp解释器进行了广告宣传.当然,Lisp有基本上它今天的形式......"
所以Lisp的是物化的,从一个抽象的概念,为实际的编程语言.
Edw*_*ETT 24
物化
具体化是一种实例化形式.当你理解一个概念时,你会采取一些抽象的东西并使其具体化,就像你提供的字典定义一样.
您可以选择将类型重新定义为居住在可能类型的抽象语法树中的术语.
您可以通过针对某种语言提出它的通用实现来实现设计模式.例如,像
template<typename T> class Singleton {
public:
static T& Instance() {
static T me;
return me;
}
protected:
virtual ~Singleton() {};
Singleton() {};
}
Run Code Online (Sandbox Code Playgroud)
在C++中将单例设计模式作为模板进行处理.
你可以将Hoare的quicksort想法变成你选择的编程语言的实现.在这种情况下,我花了很多时间将类别理论中的概念用于Haskell代码.
您可以将语言用作该语言的解释器.Larry Wall对Perl这种语言的看法被称为perl解释器.
的数据具体化和真空包具体化方面为表示它是如何在存储器的结构与共享的曲线图.
反射
具体化的另一面是反思,它采取具体的东西,并通常通过忘记一些细节来产生抽象.也许你想这样做是因为抽象更简单,或者以某种方式捕捉到你所谈论的内容的本质.
Java,C#等中的类型系统反射采用编程语言中的具体类,并为您提供类的抽象结构,使您可以访问类提供的成员列表.在这里,我们采用一种类型的具体概念,并从中生成描述其结构的抽象术语,同时丢弃任何特定值.
就像你如何将编程语言变成一个实现一样,你可能有时会走向相反的方向.虽然这通常被认为是一个坏主意,但您可以采用实现并尝试从其行为的理想属性反映语言规范.TeX 首先由Knuth 实施,没有规范.任何针对TeX的规范都反映在Knuth的实现中.
(更正式地说,如果你将反射视为一个将你从一个具体领域带到一个抽象领域的健忘仿函数,那么理想情况下,具体化就会与反射相伴随.)
我维护的反射包提供了一个reify方法,它接受一个术语并产生一个表示它的类型,然后是一个反射方法,可以让你生成一个新术语.这里的"具体"域是类型系统,抽象域是术语.
Kyn*_*nth 21
来自Haskell Wiki:
"具体化"某事是为了采取抽象的东西并将其视为物质.一个典型的例子是古人采取抽象概念(例如"胜利")并将其变成神灵的方式(例如希腊胜利女神耐克).
具体类型是表示类型的值.使用reified类型而不是真实类型意味着您可以使用它们对值进行任何操作.
yat*_*975 14
我能想到的一个用途(我确定还有其他人!)正在将一个类变成一个字典.让我们Eq
上课(/=
暂时忘记操作员):
class Eq a where
(==) :: a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)
如果我们重新启用这个类,它将成为:
data EqDict a = EqDict (a -> a -> Bool)
Run Code Online (Sandbox Code Playgroud)
可以建造,检查等.另外值得注意的是,Eq
每种类型只能有一个实例,但有多个EqDict
值.但是实例的自动构造(例如,当你为元素提供列表时获得相等)是行不通的; 你必须EqDict [a]
自己构建价值.
具体化过程就像这样(对于这种情况):
reify :: Eq a => EqDict a
reify = EqDict (==)
Run Code Online (Sandbox Code Playgroud)
使用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 ]
Run Code Online (Sandbox Code Playgroud)
如果你解开的EqDict,只是传递一个a -> a -> Bool
,你得到的..By
功能,喜欢Data.List.nubBy
和朋友-一个类似的伎俩Ord
导致Data.List.sortBy
.
即使只是在Haskell的背景下,该术语也被广泛使用.Andy Gill的reify包允许您使用递归结构并将它们转换为显式图形.Sigpfe关于延续的帖子描述了将"其余计算"的概念重新定义为可以传递的值.模板Haskell有一个reify函数(通常在编译时执行TH代码),当给定Haskell值的名称时,返回它的可用信息(声明,类型等).
所有这些案件有什么共同之处?他们谈论的是采取我们可以推理和知道的东西,但我们不能直接以编程方式操作,并将其转化为我们可以像任何其他人一样命名和传递的实际的第一类值.这通常是人们在使用这个词时想要传达的意图.