2015-12-10 26 views
7

Yığını hack yaparken, this bulundu:Ünitede bir patlama paterni gerçekten gerekli mi?

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

HLint diyor ki: “O şeyi kaldır”. Ama bence yazım hatası yok. !() yazabilmek için herhangi bir sebep var mı?

+3

Çünkü '()' zaten normal formda (ve dolayısıyla WHNF'de), burada bir patern paterni kullanmanın bir anlamı olmadığını düşünüyorum. – Jubobs

+1

Bir kurucu modelden önce bir patlama anlamsızdır - yine de değeri zorluyoruz. – chi

+2

Repo'nun bazı araştırması, bu patlama paterninin, Michael Snoyman tarafından [bu taahhütte] sunulduğunu ortaya koymaktadır (https://github.com/commercialhaskell/stack/commit/5039c19655f496926fa882c93efe2867afb97468). Belki de sorunuzu repo'nun sorun takipçisine göndermelisiniz ve ona yazarken ne düşündüğünü sormalısınız. Michael onun eşyalarını biliyor, bu yüzden bu gereksiz patlamayı bir gözetim altında bıraktığını söyleyebilirim. – Jubobs

cevap

6

Şüpheniz varsa (ve acele etmeyin), specification'a başvurun.

ifadesi

do !() <- foo 
    bar 

desugarsrules for function definition Bununla

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

için olmayan olduğu gibi şimdi rules for bang patterns, GHC kullanıcı kılavuzunda bulunmaktadır

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

eşdeğerdir -standart haskell. Orada biz onun argümanı olmaktan ⊥ veya olmasın anlamında Şimdi

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

seq is defined içine bu yeniden yazabilirsiniz bulmak. Yani ya x ⊥, ancak seq için ikinci bağımsız değişken, yani case x of ... da semantics of pattern matching göre ⊥ olduğunu. Veya x ⊥ değil ve seq ikinci bağımsız değişkenine eşittir. Her iki durumda da, yukarıdaki kod adımları geri izleme,

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

aynıdır, Yani sonuç olarak

do() <- foo 
    bar 

eşdeğerdir: bunda bir do ifadesini yapmak için hiçbir sebep yoktur.

let() = foo 
in bar 
( foo değerlendirilecektir asla)

ve

let !() = foo 
in bar 

let-ifadeler semantics for bang patterns özel hükümler var çünkü

arasında bir fark ise yoktur.

İlgili konular