【问题标题】:What is the precedence of ~, and why?〜的优先级是什么,为什么?
【发布时间】:2015-01-31 23:00:05
【问题描述】:

下面的sn-p编译:

{-# LANGUAGE TypeFamilies #-}
type family Foo a b

f :: (Foo a b ~ Int) => a -> b -> b
f = error ""

infix 类型运算符的行为似乎有所不同:

{-# LANGUAGE TypeFamilies #-}
type family a \\ b

f :: (a \\ b ~ Int) => a -> b -> b
f = error ""

GHC 抱怨 \\ 的第二个参数应该有类型 *,但 b ~ Int 有类型 Constraint。当然这可以用括号来解决,但我想知道是否还有其他方法。

我尝试使用固定声明infixl 9 \\ 设置运算符的优先级,但这并不能解决问题,表明~ 的优先级是at least 9(如果我解释正确的话)。我尝试使用this answer 中的技巧让 GHCi 告诉我~ 的优先级,但没有成功。

从技术上讲,~ 可能不是类型运算符,它更像是类似于, 的词法构造,但问题仍然存在:

  1. 为什么中缀和前缀运算符表现出不同的行为?
  2. 为什么~绑定得这么紧?
  3. 我可以做些什么来让我自己的运算符绑定得更紧密吗?

(注意:This question 询问类型函数的优先级,但没有说明 ~。)

【问题讨论】:

  • 另一个奇怪的事情是,如果我问 GHCi :k (~),它会告诉我(~) :: k -> k -> Constraint,但如果我问:i (~),它会告诉我parse error on input ‘~’。所以解析器处理~的方式似乎很奇怪。
  • 我不确定这是什么原因 - ~ 由于是内置类型函数而有一些特殊行为,也许它应该与其他事物保持一致。但是,如果这真的让您感到困扰,您可以执行type (==) = (~); infixr 0 == 之类的操作,这样在术语和类型级别之间的语法甚至会更加一致。
  • 我现在有一个GHC ticket

标签: haskell


【解决方案1】:

~ 不是运算符,它是关键字,例如 modulecase,所以我认为您只能使用括号更改优先级。

在此处查看更多信息:https://wiki.haskell.org/Keywords#.7E

【讨论】:

  • 这显然不是故事的全部。是的,~ 在模式中是语法,但在其他上下文中,它是类型运算符。
  • 它看起来像一个类型运算符,因为你可以得到它的种类,但它不可能只是 acts 像一个吗?
  • 我不够熟练,无法梳理实现的源代码,但这就是我的怀疑。
猜你喜欢
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-15
  • 2011-10-25
  • 2018-06-21
  • 2010-12-10
  • 1970-01-01
相关资源
最近更新 更多