类型签名中运算符符号周围的括号
Parenthesis around operator symbol in type signature
. :: (a -> b) -> (c -> a) -> c -> b
f . g = \ x -> f (g x)
为什么这个定义是非法的?审美选择,还是形式需要?
这是为了保持一致性。中缀运算符本身并不是您可以定义其类型或值的 表达式 。以下也不合法:
. = \f g x -> f (g x)
...尽管这基本上是您的定义所依据的内容。但是为了直接 以这种方式定义中缀的值 ,我们需要首先禁用特殊的语法状态,这是通过将其括在括号中来完成的:
(.) :: (a -> b) -> (c -> a) -> c -> b
(.) = \f g x -> f (g x)
这与定义完全相同
compose :: (a -> b) -> (c -> a) -> c -> b
compose = \f g x -> f (g x)
...然后也可以用作中缀,例如
Prelude> map (toEnum `compose` round) $ [110 + sin x * 12 | x<-[0..30]] :: String
"nxypebkvzsgbhszvkbepyxndclwyqfb"
但是你显然不会把定义写成中缀形式,比如
`compose` :: (a -> b) -> (c -> a) -> c -> b
`compose` = \f g x -> f (g x)
...虽然你可以做到
f`compose`g = \x -> f (g x)
. :: (a -> b) -> (c -> a) -> c -> b
f . g = \ x -> f (g x)
为什么这个定义是非法的?审美选择,还是形式需要?
这是为了保持一致性。中缀运算符本身并不是您可以定义其类型或值的 表达式 。以下也不合法:
. = \f g x -> f (g x)
...尽管这基本上是您的定义所依据的内容。但是为了直接 以这种方式定义中缀的值 ,我们需要首先禁用特殊的语法状态,这是通过将其括在括号中来完成的:
(.) :: (a -> b) -> (c -> a) -> c -> b
(.) = \f g x -> f (g x)
这与定义完全相同
compose :: (a -> b) -> (c -> a) -> c -> b
compose = \f g x -> f (g x)
...然后也可以用作中缀,例如
Prelude> map (toEnum `compose` round) $ [110 + sin x * 12 | x<-[0..30]] :: String
"nxypebkvzsgbhszvkbepyxndclwyqfb"
但是你显然不会把定义写成中缀形式,比如
`compose` :: (a -> b) -> (c -> a) -> c -> b
`compose` = \f g x -> f (g x)
...虽然你可以做到
f`compose`g = \x -> f (g x)