2015-12-10 20 views
7

スタックをハッキングしながら、私はthisが見つかりました:ここに本当に必要なバンパターンがありますか?

!() <- atomicModifyIORef (eoExeCache eo) $ \m' -> 
    (Map.insert name epath m',()) 

HLintは言う:「その事を取り除きます」。しかし、私はそれが誤字だとは思わない。 !()を書く理由がありますか?

+3

'()'はすでに通常の形式(したがって、WHNF内)であるため、ここではバンパターンを使用している点はありません。 – Jubobs

+1

コンストラクタパターンの前には意味がありません - とにかく値を強制しています。 – chi

+2

レポのいくつかの調査は、このバンパターンが[このコミット](https://github.com/commercialhaskell/stack/commit/5039c19655f496926fa882c93efe2867afb97468)のMichael Snoymanによって紹介されたことを示しています。おそらく、あなたはあなたの質問をレポの問題トラッカーに投稿し、それを書いているときに彼が何を考えていたのかを尋ねるべきでしょう。マイケルは彼のことを知っているので、私は彼が単に見過ごしてこの余計なものを残したと言うだろう。 – Jubobs

答えて

6

ご不明な点やお急ぎの場合は、specificationにご相談ください。

let ok !() = bar 
    ok _ = fail .. 
in foo >>= ok 

発現

do !() <- foo 
    bar 

desugarsrules for function definitionでは、これは、それが非として今rules for bang patternsは、GHCのユーザーガイドに記載されて

let ok = \x -> case x of !() -> bar 
         _ -> fail ... 
in foo >>= ok 

と等価です - 標準的なhaskell。そこに我々はその引数が⊥かではないという点で、今seq is defined

let ok = \x -> x `seq` (case x of() -> bar 
            _ -> fail ...) 
in foo >>= ok 

にこれを書き換えることができますを見つけます。したがってxは⊥ですが、seqの2番目の引数、つまりcase x of ...semantics of pattern matchingに従う⊥です。またはxは⊥ではなく、seqは第2引数と同じです。いずれの場合も、上記のコードは

これらのステップを遡っ、
let ok = \x -> case x of() -> bar 
         _ -> fail ... 
in foo >>= ok 

と同じである、という結論にそう

do() <- foo 
    bar 

と同等です:do式でそれをする理由はありません。

let() = foo 
in bar 
fooが評価されることはありません)

let !() = foo 
in bar 

レット式がsemantics for bang patternsに特別な規定を持っているので

との違いは、しかし、があります。

関連する問題