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,252
    • Issues 5,252
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 561
    • Merge requests 561
  • 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
  • #10160
Closed
Open
Issue created Mar 15, 2015 by bitemyapp@trac-bitemyapp

GHCi :sprint has odd/unhelpful behavior for values defined within the REPL

Wanted to use :sprint to help learners visualise thunk evaluation behavior in their data. Ran into some behaviors that a few people I checked with didn't have a good explanation for. I couldn't find anything in the user guide to explain this. I don't think it technically violates Haskell Report requirements, but it makes :sprint considerably less useful if you're teaching somebody non-strictness.

Examples with code in the REPL:

Prelude> let x = [1, 2, 3 :: Integer]
Prelude> :sprint x
x = [1,2,3]
-- errr, what?

Prelude> let x = Just (1 :: Integer)
Prelude> :sprint x
x = Just 1

Prelude> let just = Just
Prelude> let x = just (1 :: Integer)
Prelude> :sprint x
x = _

Prelude> let x = Just (undefined :: Integer)
Prelude> :sprint x
x = Just _

Prelude> let x = just (undefined :: Integer)
Prelude> :sprint x
x = _

Prelude> let x = [1, 2, 3 :: Integer]
Prelude> let y = x
Prelude> :sprint y
y = [1,2,3]

Prelude> let x = 1 : 2 : (3 :: Integer) : []
Prelude> :sprint x
x = [1,2,3]
Prelude> let x = [1] ++ [2] ++ [(3 :: Integer)]
Prelude> :sprint x
x = _

Prelude> let y = (:)
Prelude> let x = 1 `y` (2 `y` ((3 :: Integer) `y` []))
Prelude> :sprint x
x = _
Prelude> x
[1,2,3]
Prelude> :sprint x
x = [1,2,3]

So the behavior here seems to be:

Constructors used directly in the construction of data and are not passed functions (including polymorphic vals awaiting concrete instances)/bottoms are immediately evaluated

Example, but with loading data from a file:

Contents of the file:

x :: Num a => [a]
x = [1, 2, 3]

GHCi session:

Prelude> :t x
x :: Num a => [a]

Prelude> :sprint x
x = _

Prelude> x
[1,2,3]

Prelude> :sprint x
x = _
-- ^^ this is expected

Then when x is loaded from a file, but has a different type:

Prelude> :t x
x :: [Integer]
Prelude> :sprint x
x = _
Prelude> head x
1
Prelude> :sprint x
x = [1,2,3]
-- ^^ this is not

Now, this is a bit confusing. Earlier I was able to get :sprint to return [1, _, _] when I evaluated head x, but a couple hours later when I went to write this ticket, I couldn't reproduce that behavior.

Is there documentation that explains:

  1. Why data is shown as having been evaluated at time of declaration (seemingly) by :sprint when it's defined in the GHCi
  2. Why declaring code in GHCi and loading it from a file behaves differently with :sprint (I considered let expression in the implicit GHCi do-block...couldn't find anything to explain this)
  3. Why evaluating 'head x' forces the other values as well

Are any of these behaviors a bug? If not, are they documented anywhere? Is the "eager" treatment of constructors in GHCi a performance thing? That seems strange given I didn't have -fobject-code turned on.

:sprint not demonstrating semantics that match what I expect from a non-strict language hinders its utility as a teaching tool and means the only robust option for learners that I can find is testing evaluation with bottom values.

-- So that you know i picked "7.8.4" as the version consciously

[callen@atlantis ~/Work/fpbook]$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.4

[callen@atlantis ~/Work/fpbook]$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 7.8.4
Edited Mar 10, 2019 by bitemyapp
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking