2012-06-28 10 views
17

私は、文脈が一見ハスケルコードに表現しようとしていることを理解するために、優先順位と結合性が大きな障害となります。ハスケルの優先順位:ラムダと演算子

例えば、実験によって

blockyPlain :: Monad m => m t -> m t1 -> m (t, t1) 
blockyPlain xs ys = xs >>= \x -> ys >>= \y -> return (x, y) 

が、私は最終的にそれが意味だ、

blockyPlain xs ys = xs >>= (\x -> (ys >>= (\y -> return (x, y)))) 

の代わりとして働く

blockyPlain xs ys = xs >>= (\x -> ys) >>= (\y -> return (x, y)) 

*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)] 

ghciから(>> =)の情報を演算子として取得できます(infixl 1 >> =)。

しかし、演算子ではないので、>についての情報はありません。

あなたの誰かがこの文法を理解しやすくするために参考にしてもらえますか?

+0

[ハスケルレポート](http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-220003)はHaskell構文の決定的なリファレンスですが、おそらくBNF文法はあなたの質問に対して少し低レベルです聞いて...? –

答えて

23

ラムダのルールは非常に単純です。ラムダの本体は、不均衡な括弧に当たることなく、できるだけ右に伸びます。

f (\x -> foo (bar baz) *** quux >>= quuxbar) 
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
         body 
+3

これは最後に適用されることを意味します。つまり、( - >)は他の演算子よりも優先順位が低くなります。私は同じことが 'do'と(< - )にも当てはまると信じています。彼らはできるだけ遠くまで拡張し、最後に適用し、すべての演算子より低い優先順位を持っています。 –

+4

私は、先験的に「最初」と「最後」という言葉が本当に好きではありません。それは私が数学の教授に反対するものです。私はオペレータがオペランドを保持していると考えて「タイト」と「ルーズ」が好きです。とにかく ' - >'は2つの項を結びつけないので、実際には中置演算子ではありません。むしろラムダは式の構文形式です。だからこそ、私はオペレータの面で答えなかったのです。 – luqui

+1

両方の点がよく取られています。 「最初」と「最後」は、操作の順序について話すとき、ほとんどのk-12(数学ではない)の数学カリキュラムで使用されているフレーズです。私の試みは、一般的に使用されている用語(それほど正確ではありませんが)を非常に細かい答えに適用することでした。 –

7

経験則としては、組み込みの構文構造よりも優先順位が高いカスタム演算子を決して使うことができないようです。

if b then f *** x else f *** y 

かかわらず***の結合性の、誰もそれのようにバインドすることを期待しないだろう:例えば、この例で考える

(if b then f *** x else f) *** y 

構文要素の多くは、Haskellではありません(docaseがあるため、レイアウト構文の少ない特殊である)が、letは、他の例として使用することができる。

(let x = y in y *** x) /= ((let x = y in y) *** x) 
+2

機能のアプリケーションとレコードの更新を除いて... – luqui

関連する問題