我正在学习连接语言的基础知识,其最初的想法是函数名称连接与函数组合相同,而不是像Haskell中那样是函数应用程序。
Joy,Forth或Factor是postfix,这意味着基于堆栈,但也有一些前缀连接语言,如Om。
我想知道Haskell变体理论上是否只能通过将组合优先级(现在为9)与函数应用程序优先级(现在为10)交换(甚至等于)来实现拼接语言。
如果Haskell中的值只是零参数函数,为什么函数应用程序与函数组合不同?,函数应用程序与零参数函数组合不一样吗?
通过定义具有不同优先级的新组合和应用程序运算符并假设没有括号的简单连接是组合,可以通过简单的方式创建一个将连接语法转换为Haskell语法的解释器或预编译器吗?我认为这只是一个语法问题,我错了吗?它会避免许多我们必须在Haskell中使用括号或$运算符的情况。或者它是一个更基本的问题,而不仅仅是语法和优先级?
提示:假设Haskell中的每个函数和运算符都是前缀,我们可以忘记这个练习关于中缀符号和各种“语法糖”。
答案 0 :(得分:5)
如果Haskell中的值只是常量函数,为什么函数应用程序与函数组合不同?,函数应用程序与使用常量函数组合不一样吗?
Haskell中的值不是“常量函数”。它们也不是“无效功能”。 Haskell中唯一的函数是那些类型包含函数箭头构造函数->
的函数。
常量函数是给定任何输入的函数,它返回相同的输出。
alwaysOne x = 1
map alwaysOne [1..5] == [1, 1, 1, 1, 1]
这样一个函数的导数是0. const
函数通过忽略它的第二个参数并且总是返回第一个参数来方便地构造这样的函数。
map (const 1) [1..5] == [1, 1, 1, 1, 1]
“nullary函数”的概念仅在函数可能采用多个参数的语言中才有意义 - 在Haskell中,具有多个参数的函数的定义是具有一个参数的链式函数的定义的语法糖,在已知的过程中好奇。所有这些定义都是等价的。
foo x y = x + y
foo x = \y -> x + y
foo = \x -> \y -> x + y
(实际上,出于效率原因,GHC的运行时处理多参数函数,只为部分应用的函数构造闭包对象。)
我认为这只是语法问题,我错了吗?
连接语言的基本思想是程序表示函数,并且连接两个程序会为您提供一个表示这些函数组成的程序。因此,如果f
是一个函数,而g
是一个函数,则f g
是一个程序,表示我们将在Haskell中写为g . f
。在抽象代数术语中,存在从句法幺半群到语义幺半群的同态。这就是语法问题。
然而,还存在语义问题。这些函数必须操纵在它们之间隐式传递的程序状态,并且实际程序的状态很复杂 - 所以在实践中,连接语言倾向于使用表示一堆值的元组,因为这在实际中实现简单有效硬件。从理论上讲,程序状态可以是任何东西,例如地图或集合。
我认为Haskell的语义是这里真正的绊脚石,虽然你可以将嵌入到Haskell中,但是你需要一个连接的语言才能使其可用于日常编程。
答案 1 :(得分:1)
我的问题的最佳答案是@Daniel Wagner在他的第二条评论"Concatenative, Row-polymorphic Programming in Haskell"上引用的文章,该文由Sami Hangaslammi撰写,作为@Jon Purdy的另一篇好文章的回答,{{3} }。
它显示了“在Haskell中实现连接DSL的一种方法”,这是我真正想知道的,如果有可能,以及如何。