Add a more complete example for the special SPEC argument to the user guide
In the section for -fspec-constr
in the user guide there is an example of how to use SPEC
to force a loop to be unrolled by spec constr.
However, this argument doesn't do anything until foldl
is called with a specific argument. It wasn't clear to me exactly how this worked as the example was incomplete. Below is a complete file which shows how the optimisation unrolls the list completely such that res2 = 6
in core.
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ExistentialQuantification #-}
module Foo where
import GHC.Types
data Stream a = forall s.
Stream !(s -> Step a s) -- a stepper function
!s -- an initial state
data Step a s = Yield a !s
| Skip !s
| Done
s2 = Stream s [1,2,3]
s [] = Done
s (x:xs) = Yield x xs
res2 = Foo.foldl (+) 0 s2
foldl :: (a -> b -> a) -> a -> Stream b -> a
{-# INLINE foldl #-}
foldl f z (Stream step s) = foldl_loop SPEC z s
where
foldl_loop !sPEC z s = case step s of
Yield x s' -> foldl_loop sPEC (f z x) s'
Skip s' -> foldl_loop sPEC z s'
Done -> z
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Task |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |