Haskell 为什么(.)被称为中缀。而不是“()`

Haskell 为什么(.)被称为中缀。而不是“()`,haskell,Haskell,我了解到函数可以通过两种方式调用;前缀和中缀。例如,假设我创建了此函数: example :: [Char] -> [Char] -> [Char] example x y = x ++ " " ++ y 我可以这样称呼它为前缀: example "Hello" "World" "Hello" `example` "World" 或者像这样的中缀: example "Hello" "World" "Hello" `example` "World" 这两种方法都将产生表示字符

我了解到函数可以通过两种方式调用;前缀和中缀。例如,假设我创建了此函数:

example :: [Char] -> [Char] -> [Char]
example x y = x ++ " " ++ y
我可以这样称呼它为前缀:

example "Hello" "World"
"Hello" `example` "World"
或者像这样的中缀:

example "Hello" "World"
"Hello" `example` "World"
这两种方法都将产生表示字符串的字符列表
“Hello World”

然而,我现在正在学习函数组合,并且遇到了如下定义的函数:

(.) :: (b -> c) -> (a -> b) -> a -> c
所以,假设我想用3的乘法合成否定。我会像这样编写前缀调用:

negateComposedWithMultByThree = (.) negate (*3) 
negateComposedWithMultByThree = negate `(.)` (*3)
中缀调用如下:

negateComposedWithMultByThree = (.) negate (*3) 
negateComposedWithMultByThree = negate `(.)` (*3)
但是,当前缀调用编译时,中缀调用不会编译,而是给我错误消息:

错误:在输入“(”上分析错误

似乎,为了调用compose infix,我需要省略括号并这样称呼它:

negateComposedWithMultByThree = negate . (*3)
有人能解释一下吗?
为什么“Hello”`示例“World”
,而
否定了“(.)”(*3)
没有

此外,如果我尝试使用以下签名创建自己的函数:

(,) :: Int -> Int
(,) x = 1
它不编译,错误如下:

无效的类型签名(,):…的格式应为:


这里没有什么深奥的东西。只有两种标识符对它们的解析有不同的规则:默认中缀和默认前缀。你可以分辨哪个是哪个,因为默认中缀标识符只包含标点符号,而默认前缀标识符只包含数字、字母、撇号和下划线。

认识到默认值并不总是正确的选择,该语言提供了与默认行为不同的转换。因此有两个单独的语法规则,一个将默认中缀标识符转换为前缀(添加括号),另一个将默认前缀标识符转换为中缀(添加回号)。无法嵌套这些转换:转换为前缀形式的默认中缀标识符不是默认前缀标识符


就是这样。根本没有什么有趣的东西——所有这些都只是解析后的函数应用程序——只是语法糖。

只能对varid、qvarid、conid和qconid使用这些backtick。所以变量(限定或不限定)和构造函数(限定或不限定)。对于Haskell语法不允许的运算符:但是您可以简单地将
(.)
赋值给变量,如
让f=(+)在2`f`3
中。其思想是括号
(…)
与反勾号对标识符的作用相比,它对运算符的作用或多或少是相反的。嗯,冒着听起来愚蠢的风险,什么是词素?我的意思是,我在谷歌上搜索了它,它是有意义的,但我如何对haskell进行搜索,以便我能够理解qvarid、varid、conid和qconid是什么?我很惊讶你试图这么做当您没有尝试将
++
作为
x``(++)或
*/code>作为
(`(++)`y
*
作为
(`(*)3)时,调用
operator as
(`(*)`3)只有一个字母数字的名字可以被包裹在背板中以改变它的固定性,并且只有一个操作符的固定性通过将它包在父子中而改变。你不能混合和匹配它们,但是永远都不需要。考虑这些代码的定义:<代码>(.)= f x x> f(g x)< /代码>=代码> f.g= \x-> f(g x)< /> > =代码>(f.g)x=f(gx)
,它们的相似之处是:
com=\fgx->f(gx)
=
f`com`g=\x->f(gx)
=
(f`com`g)x=f(gx)
=
comfgx=f(gx)
这很酷,但当你说“语言提供了偏离默认行为的转换”时,你能详细说明一下吗(例如,给出一些编码示例?@ThomasCook逗号不是用于定义新的默认前缀标识符的有效标点符号。有关有效标点符号的完整列表,您可以查阅报告。@ThomasCook No,
是默认中缀标识符。
()
不是默认前缀标识符;它是默认中缀标识符到前缀形式的转换。Daniel您的评论“逗号不是用于定义新的默认前缀标识符的有效标点符号”让我开始编写函数:
($)::a->a->a($)x y=x++”++y
编译后,我就可以写“Hello”$“World”并得到“Hello World”了现在一切都有意义了,thanks@ThomasCook“例如,为什么:
(,)::Int->Int(,)x=1
没有编译?”您不能使用逗号,它们是保留的。还有一个内置构造函数
(,)
,这是两元组的前缀形式:
(,)xy==(x,y)