Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 5,249
    • Issues 5,249
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 582
    • Merge requests 582
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #11601
Closed
Open
Issue created Feb 18, 2016 by Simon Peyton Jones@simonpjDeveloper

Strict Haskell is not as strict as it probably should be

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 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.)

Trac metadata
Trac field Value
Version 7.10.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking