我正在学习连接语言的基础知识,其最初的想法是函数名称连接与函数组合相同,而不是像Haskell中那样是函数应用程序.
Joy,Forth或Factor是postfix,这意味着基于堆栈,但也有一些前缀连接语言,如Om.
我想知道Haskell变体理论上是否可以通过将组合优先级(现在为9)与函数应用程序优先级(现在为10)进行交换(甚至等于)来进行连接语言.
如果Haskell中的值只是零参数函数,为什么函数应用程序与函数组合不同?,函数应用程序与零参数函数组合相同吗?
是否有可能以简单的方式创建一个解释器或预编译器,它通过定义具有不同优先级的新组合和应用程序运算符将连接语法转换为Haskell语法,并假设没有括号的简单连接是组合?我认为这只是一个语法问题,我错了吗?它会避免许多我们必须在Haskell中使用括号或$运算符的情况.或者它是一个更基本的问题,而不仅仅是语法和优先级?
提示:假设Haskell中的每个函数和运算符都是前缀,我们可以忘记这个关于中缀符号和各种"语法糖"的练习.
haskell operator-precedence concatenative-language polish-notation
考虑以下情况.我定义了一个函数来处理元素列表,通过在头上执行操作的典型方法并在列表的其余部分上调用函数.但在元素的某些条件下(为负面,是一个特殊字符,......)我会在继续之前更改列表其余部分的符号.像这样:
f [] = []
f (x : xs)
| x >= 0 = g x : f xs
| otherwise = h x : f (opposite xs)
opposite [] = []
opposite (y : ys) = negate y : opposite ys
Run Code Online (Sandbox Code Playgroud)
因为opposite (opposite xs) = xs,我变成了多余的相反操作的情况,积累opposite . opposite . opposite ....
它发生在其他操作而不是opposite任何这样的组合物本身就是身份,就像reverse.
是否有可能使用仿函数/ monads/applicatives /箭头克服这种情况?(我不太了解这些概念).我想要的是能够定义属性或组合模式,如下所示:
opposite . opposite = id -- or, opposite (opposite y) = y
Run Code Online (Sandbox Code Playgroud)
为了使编译器或解释器避免计算相反的相反(在一些连接语言中它是可能的和简单的(本机的)).
这是一段相当简单的代码.它需要一个整数并使用商和余数分解其十进制数字.在每次调用时,它会打印一行r字符'I',其中r是最后一位数字,然后用商作为新参数调用自身.
decToUnary 0 = return ()
decToUnary n = let (q, r) = quotRem n 10 in
do
putStrLn (take r "IIIIIIIIII")
decToUnary q
Run Code Online (Sandbox Code Playgroud)
它适用于少于10位数的数字,但对于10位或更多位数字,它会对输出进行加扰.我做错了什么,为什么这样做?以下是输出的一些示例,第一个是正确的,第二个是错误的:
*Main> decToUnary 5432
II
III
IIII
IIIII
*Main> decToUnary 5432101234
IIIIIIII
III
IIIIIIIII
III
III
I
IIIIIII
III
I
I
Run Code Online (Sandbox Code Playgroud) 该signum函数是sign的通常数学定义的实现,它有条件地返回{-1,0,1}中的值.这是一个理论定义,因此,它没有考虑操作的计算成本或值的数据类型,因此乘以(-1)是改变符号的零成本理论方法.因此,它不是最有用的编程符号处理方法.
这种情况signum a == 0并不是很有用,因为您可以随时直接测试a == 0,而无需额外的计算成本signum a.至于其他两个值,我认为它们仅用于三种方式:
要么测试值是正还是负,要有条件地启动不同的代码,如:
f x y | signum x == -1 = h x y
| otherwise = g x y
Run Code Online (Sandbox Code Playgroud)或者你在操作之前1或-1之前乘以某些东西,如:
f x y = g x (y * b) where
b = signum x
Run Code Online (Sandbox Code Playgroud)或者在使用之前添加1或添加-1某些内容,如:
f x y = g x (y + b) where
b = signum x
Run Code Online (Sandbox Code Playgroud)在所有情况下,Bool标志的价值会更好.因此,我们只需要将函数分解 …