类型注解(::)的中缀优先级是多少?

23

:: 的优先级是多少?是否有运算符的优先级比它更低?

似乎 :: 的优先级低于 $,因为下面两个表达式都返回 "ab"

map head $ ["alice", "bob"] :: String
map head ["alice", "bob"] :: String
1个回答

20
:: 部分被称为类型注释。一封邮件列表中的消息指出了完全相同的结论,并得到语法的支持。具体信息请参考:https://mail.haskell.org/pipermail/beginners/2012-December/011017.html

It's not really a binary operator.

It's part of the syntax, so it has no exact precedence, but since you're asking about it, I presume you're not interested in type declarations

foo :: Int -> Double  
foo = sin . fromIntegral

but rather in expression type signatures. The production in the context-free syntax is

exp → infixexp :: [context =>] type

so the signature is for the entire infix expression:

Prelude> toEnum . floor $ 12.7 + toEnum 73 :: Char
'U'

hence if it had a precedence, it would be below 0 (the precedence of ($)).

But be aware that

"The grammar is ambiguous regarding the extent of lambda abstractions, let expressions, and conditionals. The ambiguity is resolved by the meta-rule that each of these constructs extends as far to the right as possible."

thus

Prelude> (\x -> x + x :: Int -> Int) 2

<interactive>:16:10:
    No instance for (Num (Int -> Int)) arising from a use of `+'
    Possible fix: add an instance declaration for (Num (Int -> Int))
    In the expression: x + x :: Int -> Int
    In the expression: \ x -> x + x :: Int -> Int
    In the expression: (\ x -> x + x :: Int -> Int) 2

the type signature here extends only over the x + x, since it is parsed as a part of the lambda abstraction

[ \x -> (x + x :: Int -> Int) extends farther to the right than just \x -> x + x ]

So if you want to give a type signature to a lambda abstraction, you need explicit parentheses:

Prelude> ((\x -> x + x) :: Int -> Int) 2 4

1
有没有任何情况下它的行为不像“infix (-1) ::”? - leftaroundabout
我不这么认为,在那条消息中的第二个例子似乎与 $ 完全相同的方式工作。 - Koterpillar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接