Re: [GHC] #7994: Make foldl into a good consumer
#7994: Make foldl into a good consumer -------------------------------------+------------------------------------ Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by nomeata): Ok, here is a very different approach to solving the original problem of this ticket, namely making `foldl` a good consumer. Instead of trying hard to make the compiler sufficiently smart, why not help him a little bit? So here is what I did: I created a new magic function `oneShot` (similar to `lazy` etc.). Semantically, `oneShot = λ f λ x. f x", but the unfolding will put a `OneShot` on the binder for x. So essentially, it allows the programmer to tell the compiler: I promise I will only call this function once (and if I break my promise, I won’t blame you). So now one would define {{{ foldl k z xs = foldr (\v fn -> oneShot (\z -> fn (k z v))) id xs z }}} (because at this point, we know that the result of `foldr ... id xs` is ''not'' going to be used multiple times) and voilà – good code: {{{ Foo.$wfoo :: GHC.Prim.Int# -> (# GHC.Types.Double, GHC.Types.Double #) [GblId, Arity=1, Str=DmdType <L,U>, Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 249 30}] Foo.$wfoo = \ (ww_s1ox :: GHC.Prim.Int#) -> case GHC.Prim.tagToEnum# @ GHC.Types.Bool (GHC.Prim.># 1 ww_s1ox) of _ [Occ=Dead] { GHC.Types.False -> letrec { $wgo_s1ot [Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.Double# -> GHC.Prim.Double# -> (# GHC.Types.Double, GHC.Types.Double #) [LclId, Arity=3, Str=DmdType <S,U><L,U><L,U>] $wgo_s1ot = \ (w_s1oc :: GHC.Prim.Int#) (ww1_s1oj :: GHC.Prim.Double#) (ww2_s1oo :: GHC.Prim.Double#) -> case Foo.f (GHC.Types.I# w_s1oc) of _ [Occ=Dead] { Data.Complex.:+ ww8_aYl ww9_aYm -> case ww8_aYl of _ [Occ=Dead] { GHC.Types.D# ww11_s1sa -> case ww9_aYm of _ [Occ=Dead] { GHC.Types.D# ww13_s1sc -> case GHC.Prim.tagToEnum# @ GHC.Types.Bool (GHC.Prim.==# w_s1oc ww_s1ox) of _ [Occ=Dead] { GHC.Types.False -> $wgo_s1ot (GHC.Prim.+# w_s1oc 1) (GHC.Prim.+## ww1_s1oj ww11_s1sa) (GHC.Prim.+## ww2_s1oo ww13_s1sc); GHC.Types.True -> (# GHC.Types.D# (GHC.Prim.+## ww1_s1oj ww11_s1sa), GHC.Types.D# (GHC.Prim.+## ww2_s1oo ww13_s1sc) #) } } } }; } in $wgo_s1ot 1 0.0 0.0; GHC.Types.True -> (# Foo.foo1, Data.Complex.$fFloatingComplex1 #) } }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7994#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC