
Yes, it actually cycles the argument and then maps over the result—horrible in every way.
But this is well-known: You usually cannot “modify” cyclic data structures without breaking them.
Of course its cool that with the above definition of `cycle` + fusion, we can suddenly `map` over a cyclic structure without breaking it, but maybe that’s a tad too much magic? Especially as people probably don’t have a good feeling for when this happens and when not? OTOH, I don’t
#9398: Data.List.cycle is not a good producer -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: Type: bug | Status: new Priority: normal | Milestone: 7.8.4 Component: | Version: 7.8.3 libraries/base | Keywords: Resolution: | Architecture: Unknown/Multiple Operating System: | Difficulty: Easy (less than 1 Unknown/Multiple | hour) Type of failure: Runtime | Blocked By: performance bug | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by dfeuer): Replying to [comment:16 nomeata]: think it hurts either, and nice surprises are – well – nice. Well, I agree that magic can be a problem, but if it falls out of something that tends to be good, that's not a major issue.
Did you investigate why `foldr (+) 0 $ take 30000000 $ map (* 13) $ cycle [1,8,4,0,(5::Int)]` allocates more?
I'm not entirely sure, but it looks to me like it's all about unboxing. Somehow, the Prelude version is able to unbox all the `Int`s, whereas this one is not. If I replace the `(+)` with {{{#!hs {-# NOINLINE g #-} g a b = a }}} then both versions run in constant space. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9398#comment:17 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler