什么是类型注释的中缀优先级(::)

Leo*_*ang 21 haskell

优先级是什么::,是否有任何运营商的优先级甚至低于它?

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

map head $ ["alice", "bob"] :: String
map head ["alice", "bob"] :: String
Run Code Online (Sandbox Code Playgroud)

Kot*_*lar 18

::部分称为类型注释.

邮件列表上的消息指向完全相同的结论,由语法支持:

https://mail.haskell.org/pipermail/beginners/2012-December/011017.html

它不是真正的二元运算符.

它是语法的一部分,所以它没有确切的优先级,但既然你在询问它,我认为你对类型声明不感兴趣

foo :: Int -> Double  
foo = sin . fromIntegral
Run Code Online (Sandbox Code Playgroud)

而是表达式签名.无上下文语法的生成是

exp ? infixexp :: [context =>] type
Run Code Online (Sandbox Code Playgroud)

所以签名是针对整个中缀表达式的:

Prelude> toEnum . floor $ 12.7 + toEnum 73 :: Char
'U'
Run Code Online (Sandbox Code Playgroud)

因此,如果它有一个优先级,它将低于0(($)的优先级).

但请注意

"关于lambda抽象,表达式和条件的范围,语法是模棱两可的.模糊性由元规则解决,即这些结构中的每一个都尽可能向右延伸."

从而

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
Run Code Online (Sandbox Code Playgroud)

这里的类型签名只扩展到x + x,因为它被解析为lambda抽象的一部分

[ \x -> (x + x :: Int -> Int)延伸到更远的地方而不仅仅是 \x -> x + x]

因此,如果要为lambda抽象提供类型签名,则需要明确的括号:

Prelude> ((\x -> x + x) :: Int -> Int) 2 4
Run Code Online (Sandbox Code Playgroud)