Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When you write <code>[1..1000000]</code>, what GHC really does is create an object that contains <code>1</code> and <code>1000000</code> that describes how to build the list of interest; that object is called a "thunk". The list is only built as necessary to satisfy case scrutinees; for example, you might write:</p> <pre><code>printList [] = putStrLn "" printList (x:xs) = putStrLn (show x) &gt;&gt; printList xs main = printList [1..1000000] </code></pre> <p>Which evaluates like this:</p> <pre><code>main = { definition of main } printList [1..1000000] = { list syntax sugar } printList (enumFromTo 1 1000000) = { definition of printList } case enumFromTo 1 1000000 of [] -&gt; putStrLn "" x:xs -&gt; putStrLn (show x) &gt;&gt; printList xs = { we have a case, so must start evaluating enumFromTo; I'm going to skip a few steps here involving unfolding the definition of enumFromTo and doing some pattern matching } case 1 : enumFromTo 2 1000000 of [] -&gt; putStrLn "" x:xs -&gt; putStrLn (show x) &gt;&gt; printList xs = { now we know which pattern to choose } putStrLn (show 1) &gt;&gt; printList (enumFromTo 2 1000000) </code></pre> <p>Then you'd find that <code>1</code> was printed to the console, and we'd start from near the top with <code>enumFromTo 2 1000000</code> instead of <code>enumFromTo 1 1000000</code>. Eventually, you'd get all the numbers printed and it would come time to evaluate</p> <pre><code>printList (enumFromTo 1000000 1000000) = { definition of printList } case enumFromTo 1000000 1000000 of [] -&gt; putStrLn "" x:xs -&gt; putStrLn (show x) &gt;&gt; printList xs = { skipping steps again to evaluate enumFromTo } case [] of [] -&gt; putStrLn "" x:xs -&gt; putStrLn (show x) &gt;&gt; printList xs = { now we know which pattern to pick } putStrLn "" </code></pre> <p>and evaluation would be finished.</p> <p>The reason we need streams is a bit subtle. The original paper, <a href="http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.104.7401" rel="nofollow noreferrer">Stream fusion: From lists to streams to nothing at all</a>, probably has the most complete explanation. The short version is that when you have a long pipeline:</p> <pre><code>concatMap foo . map bar . filter pred . break isSpecial </code></pre> <p>...it's not so obvious how to get the compiler to compile away all the intermediate lists. You might notice that we can think of the lists as having a sort of "state" that's being iterated, and that each of these functions, rather than traversing a list, is just changing the way the state gets modified on each iteration. The <code>Stream</code> type tries to make this explicit, and the result is stream fusion. Here's how it looks: we first convert all these functions into stream versions:</p> <pre><code>(toList . S.concatMap foo . fromList) . (toList . S.map bar . fromList) . (toList . S.filter pred . fromList) . (toList . S.break isSpecial . fromList) </code></pre> <p>then observe that we can always annihilate <code>fromList . toList</code>:</p> <pre><code>toList . S.concatMap foo . S.map bar . S.filter pred . S.break . fromList </code></pre> <p>...and then the magic happens because the chain <code>S.concatMap foo . S.map bar . S.filter pred . S.break</code> builds up an iterator explicitly rather than building it implicitly by internally building and then immediately annihilating actual lists.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload