类型签名中的运算符符号周围的括号

0 syntax haskell operators special-characters type-signature

. :: (a -> b) -> (c -> a) -> c -> b
f . g = \ x -> f (g x)
Run Code Online (Sandbox Code Playgroud)

为什么这个定义是非法的?审美选择还是形式上的必然?

lef*_*out 6

这是为了保持一致性.中缀运算符本身不是您可以定义其类型或值的表达式.以下也不合法:

. = \f g x -> f (g x)
Run Code Online (Sandbox Code Playgroud)

...虽然这基本上是你的定义被贬低的.但是为了这种方式直接定义中缀的值,我们需要首先禁用特殊的语法状态,并通过将其包装在括号中来完成:

(.) :: (a -> b) -> (c -> a) -> c -> b
(.) = \f g x -> f (g x)
Run Code Online (Sandbox Code Playgroud)

这与定义完全相同

compose :: (a -> b) -> (c -> a) -> c -> b
compose = \f g x -> f (g x)
Run Code Online (Sandbox Code Playgroud)

......然后也可以用作中缀

Prelude> map (toEnum `compose` round) $ [110 + sin x * 12 | x<-[0..30]] :: String
"nxypebkvzsgbhszvkbepyxndclwyqfb"
Run Code Online (Sandbox Code Playgroud)

但你显然不会用中缀形式写定义,比如

`compose` :: (a -> b) -> (c -> a) -> c -> b
`compose` = \f g x -> f (g x)
Run Code Online (Sandbox Code Playgroud)

......虽然你能做到

f`compose`g = \x -> f (g x)
Run Code Online (Sandbox Code Playgroud)

  • 如果“3 + 4”是常规函数应用,它将被解析为“(((3)(+))(4))”:函数“3”应用于“+”和“4”。在Scheme中,它实际上会以这种方式进行解析,因此需要将其写成“(+ 3 4)”才能有意义。Haskell 不这样做是因为我们想要实际的中缀表示法,因为大多数人会认为 `3 + 4` 比 `(+ 3 4)` 更具可读性。 (2认同)