[GHC] #7994: Make foldl into a good consumer
GHC
ghc-devs at haskell.org
Fri Jan 24 16:17:40 UTC 2014
#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
More information about the ghc-tickets
mailing list