content: {-# LANGUAGE ExistentialQuantification #-}
  
  -- This test is really meant for human looking; do a -ddump-simpl.
  
  -- The definition that you want to look at is for foo.
  -- It produces a nested unfold that should look something
  -- like the code below.  Note the 'lvl1_shW'.  It is BAD
  -- if this is a lambda instead; you get a lot more allocation
  -- See Note [Escaping a value lambda] in SetLevels
  
  
  {-
        $wunfold_shU =
  	\ (ww_she :: [[a_abm]]) (ww1_shf :: Data.Maybe.Maybe (Stream.Stream a_abm)) ->
  	  case ww1_shf of wild2_afo {
  	    Data.Maybe.Nothing ->
  	      case ww_she of wild_ad6 {
  		[] -> GHC.Base.[] @ a_abm;
  		: x_ado xs1_adp ->
  		  $wunfold_shU
  		    xs1_adp
  		    (Data.Maybe.Just
  		       @ (Stream.Stream a_abm) (Stream.Stream @ a_abm @ [a_abm] 
  								*** lvl1_shW *** 
  								x_ado))
  	      };
  	    Data.Maybe.Just ds3_afJ ->
  	      case ds3_afJ of wild3_afL { Stream.Stream @ s1_afN stepb_afO sb_afP ->
  	      case stepb_afO sb_afP of wild4_afR {
  		Stream.Done -> $wunfold_shU ww_she (Data.Maybe.Nothing @ (Stream.Stream a_abm));
  		Stream.Yield x_afV sb'_afW ->
  		  GHC.Base.:
  		    @ a_abm
  		    x_afV
  		    ($wunfold_shU
  		       ww_she
  		       (Data.Maybe.Just
  			  @ (Stream.Stream a_abm) (Stream.Stream @ a_abm @ s1_afN stepb_afO sb'_afW)));
  		Stream.Skip sb'_afZ ->
  		  $wunfold_shU
  		    ww_she
  		    (Data.Maybe.Just
  		       @ (Stream.Stream a_abm) (Stream.Stream @ a_abm @ s1_afN stepb_afO sb'_afZ))
  	      }
  	      }
  -}
  
  
  
  module Main( main, foo ) where
  -- Must export foo to make the issue show up
  
  import Prelude hiding ( concatMap, map) 
  
  main = print (sum (foo [[1,2], [3,4,5]]))
  
  foo :: Num a => [[a]] -> [a]
  foo xss = Main.concatMap (\xs -> Main.map (+1) xs) xss
  
  
  instance StreamableSequence [] where
    stream = listToStream
    unstream = streamToList
    -- These inline pragmas are useless (see #5084)
  {-
    {-# INLINE stream #-}
    {-# INLINE unstream #-}
  -}
  
  listToStream :: [a] -> Stream a
  listToStream xs = Stream next xs
    where next []     = Done
          next (x:xs) = Yield x xs
  {-# INLINE [0] listToStream #-}
  
  streamToList :: Stream a -> [a]
  streamToList (Stream next s) = unfold s
    where unfold s =
            case next s of
              Done       -> []
              Skip    s' ->     unfold s'
              Yield x s' -> x : unfold s'
  {-# INLINE [0] streamToList #-}
  
  {-# RULES
  "stream/unstream"
    forall s. listToStream (streamToList s) = s
    #-}
              
  map :: (a -> b) -> [a] -> [b]
  map f = unstream . mapS f . stream
  {-# INLINE map #-}
  
  concatMap :: (a -> [b]) -> [a] -> [b]
  concatMap f = unstream . concatMapS (stream . f) . stream
  {-# INLINE concatMap #-}
  
  
  data Stream a = forall s. Stream (s -> Step a s) s
  
  data Step a s = Done
                | Yield a s
                | Skip    s
  
  class StreamableSequence seq where
    stream   :: seq a -> Stream a
    unstream :: Stream a -> seq a
  
    -- axiom: stream . unstream = id
    -- These inline pragmas are useless (see #5084)
  {-
    {-# INLINE stream #-}
    {-# INLINE unstream #-}
  -}
  
  {-
  --version that does not require the sequence type
  --to be polymorphic in its elements:
  
  class StreamableSequence seq a | seq -> a where
    stream   :: seq -> Stream a
    unstream :: Stream a -> seq
  -}
  
  
  mapS :: (a -> b) -> Stream a -> Stream b
  mapS f (Stream next s0) = Stream next' s0
    where next' s = case next s of
            Done       -> Done
            Skip    s' -> Skip        s'
            Yield x s' -> Yield (f x) s'
  {-# INLINE [0] mapS #-}
  
              
  concatMapS :: (a -> Stream b) -> Stream a -> Stream b
  concatMapS f (Stream step s) = Stream step' (s, Nothing)
    where step' (s, Nothing) =
            case step s of
              Yield x s' -> Skip (s', Just (f x))
              Skip    s' -> Skip (s', Nothing)
              Done       -> Done
  
          step' (s, Just (Stream stepb sb)) =
            case stepb sb of
              Yield x sb' -> Yield x (s, Just (Stream stepb sb'))
              Skip    sb' -> Skip (s, Just (Stream stepb sb'))
              Done        -> Skip (s, Nothing)
  {-# INLINE [0] concatMapS #-}
  
  