title: who to wirte a correct pull function
body: <p>I want to implement pull-stream by C++ , reference "<a href="https://github.com/pull-stream/pull-stream/blob/master/pull.js" rel="nofollow noreferrer">https://github.com/pull-stream/pull-stream/blob/master/pull.js</a>"</p>
  
  <p>But I got this error:</p>
  
  <pre><code>error: no matching function for call to 'pull'
  note: candidate function template not viable: requires single argument 'stream', but 3 arguments were provided
  note: candidate function template not viable: requires 2 arguments, but 3 were provided
  
  </code></pre>
  
  <p>my code:</p>
  
  <pre><code>template &lt;typename T&gt;
  auto values(T &amp;&amp; begin, T &amp;&amp; end){
      return [&amp;](bool abort, auto cb){
  
          if(begin != end){
              cb(false, *begin++);
          }
          else{
              cb(true, *begin);
          }
      };
  };
  </code></pre>
  
  <p>values, source function.</p>
  
  <pre><code>template &lt;typename T, typename R&gt;
  auto log(R read){
  
      std::function&lt;void (bool, T)&gt; more = [&amp;](bool done, T val){
          if(!done){
              cout &lt;&lt; val &lt;&lt; endl;
              read(false, more);
          }
      };
  
      read(false, more);
  }
  </code></pre>
  
  <p>log, sink function.</p>
  
  <pre><code>template &lt;typename T&gt;
  T pull(T &amp;&amp; stream){
      return stream;
  }
  </code></pre>
  
  <pre><code>template &lt;typename R, typename S&gt;
  auto pull(R &amp;&amp; read, S &amp;&amp; sink){
      return sink(read);
  }
  </code></pre>
  
  <p>pull(source, sink)</p>
  
  <pre><code>template &lt;typename R, typename T, typename... Ts&gt;
  auto pull(R &amp;&amp; read, T &amp;&amp; through, Ts... args){
      return pull(through(read), args...);
  }
  </code></pre>
  
  <p>pull(source, through..., sink)</p>
  
  <pre><code>int main()
  {
      vector&lt;int&gt; vec;
      vec.push_back(1);
      vec.push_back(2);
  
      auto vals = values(vec.begin(), vec.end());
  
      auto mapper = [&amp;](int val){return val * 2;};
      auto timesTwo = Map&lt;int&gt;(mapper);
  
      pull(vals, timesTwo, log); // error, how to write a correct `pull` function, make this line run ok
  }
  </code></pre>
  
  <p>link source->through->sink. work wrong.</p>
  
  <pre><code>int main()
  {
      vector&lt;int&gt; vec;
      vec.push_back(1);
      vec.push_back(2);
  
      auto vals = values(vec.begin(), vec.end());
  
      auto mapper = [&amp;](int val){return val * 2;};
      auto timesTwo = Map&lt;int&gt;(mapper);
  
  //    pull(vals, timesTwo, log);
  
      auto newVals = pull(vals, timesTwo, timesTwo); // work ok
  
      bool ended = false;
      do {
          newVals(false, [&amp;](bool done, auto val){
              ended = done;
              if (ended) {
                  return;
              }
              cout &lt;&lt; val &lt;&lt; endl;
          });
      } while (!ended);
  }
  </code></pre>
  
  <p>link source->through->through.
  work right. output 4 8</p>
  
  <p><a href="http://coliru.stacked-crooked.com/a/ba79c63a338f0b8e" rel="nofollow noreferrer">Correct Eample</a></p>