Haskell Precedence:Lambda和运算符

nin*_*ing 18 grammar haskell operator-precedence

我发现优先级和关联性是一个很大的障碍,让我理解语法乍看之下对haskell代码的表达.

例如,

blockyPlain :: Monad m => m t -> m t1 -> m (t, t1)
blockyPlain xs ys = xs >>= \x -> ys >>= \y -> return (x, y)
Run Code Online (Sandbox Code Playgroud)

通过实验,我终于明白了,

blockyPlain xs ys = xs >>= (\x -> (ys >>= (\y -> return (x, y))))
Run Code Online (Sandbox Code Playgroud)

代替

blockyPlain xs ys = xs >>= (\x -> ys) >>= (\y -> return (x, y))
Run Code Online (Sandbox Code Playgroud)

其作用如下:

*Main> blockyPlain [1,2,3] [4,5,6]
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
Run Code Online (Sandbox Code Playgroud)

我可以从ghci获取信息(>> =)作为运算符,(infixl 1 >> =).

但是没有信息 - >因为它不是运营商.

你们中的某些人可以提供一些参考来使这个语法更容易掌握吗?

luq*_*qui 25

lambdas的规则非常简单:lambda的主体尽可能向右延伸而不会碰到不平衡的括号.

f (\x -> foo (bar baz) *** quux >>= quuxbar)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       body
Run Code Online (Sandbox Code Playgroud)

  • 我真的不喜欢优先级的"第一"和"最后"这两个术语 - 我认为它将分组与评估顺序混为一谈.这是我在数学教学中遇到的问题.我喜欢"紧"和"松",认为操作员坚持他们的操作.无论如何,` - >`实际上不是一个中缀运算符,因为它不连接两个项; 相反,lambda是表达式的句法形式.这就是为什么我没有回答运营商的问题. (5认同)
  • 这意味着它适用于最后.也就是说,( - >)的优先级低于任何其他运算符.我相信`do`和(< - )也是如此,它们尽可能地扩展,最后应用,并且优先级低于任何运算符. (3认同)

Jon*_*ård 7

一个好的经验法则似乎是你永远不能创建一个优先于内置语法结构的自定义运算符.例如,考虑这个例子:

if b then f *** x else f *** y
Run Code Online (Sandbox Code Playgroud)

无论相关性如何***,没有人会期望它能够绑定为:

(if b then f *** x else f) *** y
Run Code Online (Sandbox Code Playgroud)

有没有在Haskell很多语法结构的(do并且case是有点特殊的,因为布局的语法),但let可以作为一个例子:

(let x = y in y *** x) /= ((let x = y in y) *** x) 
Run Code Online (Sandbox Code Playgroud)