5

我正在学习连接语言的基础知识,其最初的想法是函数名称连接与函数组合相同,而不是像 Haskell 中的函数应用程序。

Joy、Forth 或 Factor 是后缀,这意味着基于堆栈,但也有一些前缀连接语言,例如 Om。

我想知道 Haskell 变体理论上是否可以通过将组合优先级(现在为 9)与函数应用程序优先级(现在为 10)交换(甚至等于)来成为一种连接语言。

如果 Haskell 中的值只是零参数函数,为什么函数应用与函数组合不同?,函数应用与用零参数函数组合不一样吗?

是否有可能以简单的方式制作一个解释器或预编译器,通过定义具有不同优先级的新组合和应用运算符,并将连接语法转换为 Haskell 语法,并假设没有括号的简单连接是组合?我认为这只是语法问题,我错了吗?它可以避免许多我们必须在 Haskell 中使用括号或 $ 运算符的情况。或者它是一个更根本的问题,而不仅仅是语法和优先级?

提示:假设 Haskell 中的每个函数和运算符都是前缀,我们可以在这个练习中忘记中缀符号和各种“语法糖”。

4

2 回答 2

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]

“空函数”的概念只有在函数可以接受多个参数的语言中才有意义——在 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 的语义是这里真正的绊脚石,虽然您可以串联 DSL 嵌入到 Haskell 中,但您需要一种串联语言才能使其可用于日常编程。

于 2014-12-31T05:57:59.090 回答
1

我的问题的最佳答案是@Daniel Wagner 在他的第二条评论“Haskell 中的串联、行多态编程”中引用的文章,该文章由 Sami Hangaslammi 撰写,作为对 @Jon Purdy 另一篇好文章的回答,“为什么串联编程很重要”

它展示了“在 Haskell 中实现连接 DSL 的一种方法”,这是我真正想知道的是否可行,以及如何实现。

于 2015-11-05T18:43:40.117 回答