
#11601: Strict Haskell is not as strict as it probably should be -------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.3 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Consider this with `-XStrict` {{{ f y = let Just x = blah[y] in body[y,x] }}} Suppose that in a call to `f`, * `blah` returns `Nothing` * but `body` does not use `x` Should `f` succeed? For sure, `blah` will be evaluated to HNF before `body` is started, but is the match against `Just` done strictly too? According to [http://downloads.haskell.org/~ghc/master/users- guide/glasgow_exts.html#recursive-and-polymorphic-let-bindings our current semantics], in the match against `Just` is ''not'' done strictly, so the call should succeed. I think that’s unexpected and probably wrong. The translation goes like this: {{{ !(Just x) = blah ==> (FORCE) v = blah; Just x = v (and add a seq on v) ==> (SPLIT) v = blah; x = case v of Just x -> x }}} So we finish up with {{{ f y = let v = blah[y] in let x = case v of Just x -> x in v `seq` body[y,x] }}} I don’t think that’s what we intended, because there's a thunk for `x`. If the pattern can fail, I think we want the FORCE rule to say this: {{{ Replace any binding !p = e with v = case e of p -> (v1,..,vn); (v1,..,vn) = v and replace e0 with v seq e0, where v is fresh and v1..vn are the variable(s) bound by p }}} (Compare with the text at the above link.) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11601 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler