Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,260
    • Issues 4,260
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 402
    • Merge Requests 402
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #9441

Closed
Open
Opened Aug 14, 2014 by David Feuer@treeowlReporter

CSE should deal with letrec

If I redefine

{-# INLINE reverse #-}
reverse :: [a] -> [a]
reverse xs = build $ \c n -> foldl (\a x -> x `c` a) n xs

and then write a couple test cases:

appRev xs ys = xs ++ reverse ys
revAppRev xs ys = reverse xs ++ reverse ys

I end up getting some rather annoying code duplication (lots of stuff omitted from the following):

Rec {
poly_go_r2v3
poly_go_r2v3 =
  \ @ a_a2nF ds_a2zc eta_Xl ->
    case ds_a2zc of _ {
      [] -> eta_Xl;
      : y_a2zh ys_a2zi -> poly_go_r2v3 ys_a2zi (: y_a2zh eta_Xl)
    }
end Rec }

reverse
reverse = \ @ a_a2nF eta_B1 -> poly_go_r2v3 eta_B1 ([])

Rec {
revAppRev2
revAppRev2 =
  \ @ a_a2y7 ds_a2zc eta_B1 ->
    case ds_a2zc of _ {
      [] -> eta_B1;
      : y_a2zh ys_a2zi -> revAppRev2 ys_a2zi (: y_a2zh eta_B1)
    }
end Rec }

Rec {
revAppRev1
revAppRev1 =
  \ @ a_a2y7 ds_a2zc eta_B1 ->
    case ds_a2zc of _ {
      [] -> eta_B1;
      : y_a2zh ys_a2zi -> revAppRev1 ys_a2zi (: y_a2zh eta_B1)
    }
end Rec }

Rec {
appRev1
appRev1 =
  \ @ a_a2xE ds_a2zc eta_B1 ->
    case ds_a2zc of _ {
      [] -> eta_B1;
      : y_a2zh ys_a2zi -> appRev1 ys_a2zi (: y_a2zh eta_B1)
    }
end Rec }

The reverse function was inlined three times. In each case, there was no fusion, so build was inlined and the resulting copy of the reverse worker lifted to the top level. It would seem to me that once simplification is complete, it should be safe to merge all these copies into one. They are all Rec {\ ... -> ...} forms, so I don't think this has any potential to introduce undesirable sharing.

Trac metadata
Trac field Value
Version 7.8.2
Type FeatureRequest
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
Edited Mar 09, 2019 by Simon Peyton Jones
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: ghc/ghc#9441