In caso di dubbio (e non di fretta) consultare lo specification.
L'espressione
do !() <- foo
bar
desugars a
let ok !() = bar
ok _ = fail ..
in foo >>= ok
A rules for function definition questo equivale a
let ok = \x -> case x of !() -> bar
_ -> fail ...
in foo >>= ok
Ora la rules for bang patterns sono nel manuale d'uso GHC, perché non è haskell standard. ci troviamo che possiamo riscrivere questo in
let ok = \x -> x `seq` (case x of() -> bar
_ -> fail ...)
in foo >>= ok
Ora seq
is defined in termini di suo argomento essere ⊥ oppure no. Quindi, x
è ⊥, ma il secondo argomento a seq
, ovvero lo case x of ...
è anche ⊥ in base allo semantics of pattern matching. O x
non è ⊥ e seq
equivale al suo secondo argomento. In entrambi i casi, il codice è identico a
let ok = \x -> case x of() -> bar
_ -> fail ...
in foo >>= ok
che, ripercorrendo questi passaggi, è equivalente a
do() <- foo
bar
In conclusione: Non v'è alcun motivo per farlo in un'espressione do
.
V'è, tuttavia, una differenza tra
let() = foo
in bar
(dove sarà mai essere valutati foo
) e
let !() = foo
in bar
perché let-espressioni hanno disposizioni speciali nel semantics for bang patterns.
fonte
2015-12-10 14:27:30
Poiché '()' è già nella forma normale (e, quindi, in WHNF), non penso che ci sia un punto nell'utilizzo di un modello di scoppio, qui. – Jubobs
Un botto prima di un modello di costruzione non ha senso - stiamo forzando comunque il valore. – chi
Alcune indagini sul repository rivelano che questo modello bang è stato introdotto da Michael Snoyman in [questo commit] (https://github.com/commercialhaskell/stack/commit/5039c19655f496926fa882c93efe2867afb97468). Forse dovresti pubblicare la tua domanda nel tracker dei problemi del repository e chiedergli cosa stava pensando al momento di scriverlo. Michael conosce le sue cose, quindi direi che ha semplicemente lasciato questo superfluo botto in una svista. – Jubobs