Yro*_*irg 7 language-agnostic haskell programming-languages functional-programming function
在Haskell函数->中给出了type(),它不是代数数据类型构造函数,并且不能将它重新实现为与(->)相同.
所以我想知道,哪些语言可以让我写出我的版本(->)?这个属性如何调用?
UPD通过讨论重新制定了问题:
哪种语言没有->原始类型?
为什么->有必要的原始?
Kri*_*ski 12
我想不出任何将箭头作为用户定义类型的语言.原因是箭头 - 函数的类型 - 被烘焙到类型系统中,一直到简单类型的lambda演算.箭头类型必须是语言的基础,这直接来自于你在lambda演算中形成函数的方式是通过lambda抽象(在类型级别引入箭头).
虽然Marcin恰如其分地指出你可以用自由点编程,但这并没有改变你正在做的事情的本质.使用没有箭头类型的语言作为原语违背了Haskell最基本的构建块.(您在问题中引用的语言.)
将箭头作为基本类型也与构造逻辑共享一些重要的联系:您可以将函数箭头类型视为直觉逻辑的含义,以及具有该类型作为"证据"的程序.(也就是说,如果你有类型A - > B的东西,你有一个证据,它采用A类的一些前提,并为B生成证明.)
事实上,你对使用含有箭头的语言感到不安可能意味着你并没有从根本上理解为什么他们如此依赖于语言的设计,也许是时候阅读Ben Pierce的几章了. "类型和编程语言" 链接.
编辑:您总是可以查看那些没有强大功能概念的语言,并且可以根据其他方式定义语义 - 例如,即时或PostScript - 但在这些语言中,您没有定义归纳数据类型与Haskell,ML或Coq等函数式语言相同.换句话说,在为数据类型定义构造函数的任何语言中,箭头都是从这些类型的构造函数中自然产生的.但是在您没有以典型方式定义归纳数据类型的语言中,您不会自然地获得箭头类型,因为语言不会以这种方式工作.
另一个编辑:我会再坚持一个评论,因为我昨晚想到了它.函数类型(和函数抽象)构成了几乎所有编程语言的基础 - 至少在某种程度上,即使它是"幕后".但是,有一些语言旨在定义其他语言的语义.虽然这与您所说的不完全匹配,但PLT Redex就是这样一个系统,用于指定和调试编程语言的语义.这不是从从业者的角度超好用(除非你的目标是设计新的语言,在这种情况下,它是相当有用的),但也许适合你想要什么.
您是指 SICP 中的元循环评估器吗?能够编写自己的 DSL 吗?如果您创建自己的“函数类型”,则必须自己负责“应用”它。
举个例子,您可以在 C 中创建自己的“函数”,使用包含函数指针的查找表,并使用整数作为函数。当然,您必须为此类“函数”提供自己的“调用”函数:
void call( unsigned int function, int data) {
lookup_table[function](data);
}
Run Code Online (Sandbox Code Playgroud)
您可能还需要一些从原始函数创建更复杂函数的方法,例如使用整数数组来表示“原始函数”的顺序执行1, 2, 3, ...,并最终为自己发明全新的语言。
我认为早期的汇编程序没有能力创建可调用的“宏”,必须使用 GOTO。
您可以使用蹦床来模拟函数调用。您可以只存储全局变量,也许可以使用浅绑定。在这种语言中,“函数”是可定义的,尽管不是原始类型。
因此,语言中的函数并不是必需的,尽管它很方便。
在 Common Lisp 中defun,只不过是一个关联名称和可调用对象的宏(尽管lambda仍然是内置的)。在 AutoLisp 中最初根本没有特殊的函数类型,函数直接由带引号的s表达式列表表示,第一个元素是参数列表。您可以在 AutoLisp 中直接通过符号使用cons和函数来构造函数:list
(setq a (list (cons 'x NIL) '(+ 1 x)))
(a 5)
==> 6
Run Code Online (Sandbox Code Playgroud)
某些语言(如 Python)支持不止一种原始函数类型,每种类型都有其调用协议 - 即生成器支持多次重入和返回(即使在语法上通过使用相同的def关键字)。您可以轻松想象一种语言,它可以让您定义自己的调用协议,从而创建新的函数类型。
编辑:作为一个例子,考虑在函数调用中处理多个参数,自动柯里化或自动可选参数之间的选择等。在 Common LISP 中,您可以轻松地为自己创建两个不同的宏来直接call表示两个调用协议。考虑函数返回多个值,不是通过聚合(Haskell 中的元组),而是直接返回指定的接收变量/槽。都是不同类型的函数。