为什么(。)称为中缀。而不是`(。)`

Tho*_*ook 2 haskell

我了解到可以通过两种方式调用函数:前缀和中缀。例如,说我创建了这个函数:

example :: [Char] -> [Char] -> [Char]
example x y = x ++ " " ++ y
Run Code Online (Sandbox Code Playgroud)

我可以这样称呼它为前缀:

example "Hello" "World"
Run Code Online (Sandbox Code Playgroud)

或像这样的中缀:

"Hello" `example` "World"
Run Code Online (Sandbox Code Playgroud)

两者都会导致代表字符串的字符列表"Hello World"

但是,我现在正在学习函数组成,并且遇到了如下定义的函数:

(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)

所以,说我想乘以三来求和。我会像这样写前缀调用:

negateComposedWithMultByThree = (.) negate (*3) 
Run Code Online (Sandbox Code Playgroud)

和infix调用类似:

negateComposedWithMultByThree = negate `(.)` (*3)
Run Code Online (Sandbox Code Playgroud)

但是,虽然前缀调用可以编译,但infix调用却不会,而是显示错误消息:

错误:解析输入'('

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

negateComposedWithMultByThree = negate . (*3)
Run Code Online (Sandbox Code Playgroud)

谁能对此有所启示?为什么"Hello" `example` "World"同时negate `(.)` (*3)不?

另外,如果我尝试使用这样的签名来实现自己的功能:

(,) :: Int -> Int
(,) x = 1
Run Code Online (Sandbox Code Playgroud)

它无法编译,并显示以下错误:

“无效的类型签名(,):...的形式应为::”

Dan*_*ner 13

这里没有深处。关于标识符的解析,只有两种标识符具有不同的规则:by-default-infix和by-default-prefix。您可以知道是哪个,因为默认前缀标识符仅包含标点符号,而默认前缀标识符仅包含数字,字母,撇号和下划线。

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

而已。根本上没有什么有趣的-解析后它们全部成为函数应用程序-仅仅是语法糖。

  • 为了定义新的默认前缀标识符,@ ThomasCook逗号不是有效的标点符号。您可以查阅报告以获取有效标点的完整列表。 (4认同)
  • @ThomasCook不,`是默认的前缀标识符。(。)不是*默认前缀标识符;它是将默认的前缀标识符转换为前缀形式。 (3认同)
  • 丹尼尔(Daniel)的评论“逗号对于定义新的默认前缀标识符不是有效的标点符号”使我开始编写一个函数:`($):: a-> a-> a($)xy = x + +“” ++ y`编译后,我便可以编写“ Hello” $“ World”并获得“ Hello World”现在,一切都变得有意义了,谢谢 (2认同)