<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Funktionale Spielereien]]></title><description><![CDATA[<p>Ich bin gerade dabei, ein wenig mit lambda-Ausdrücken rumzuspielen und wollte mal wissen, ob man sowas hier mit C++ realisieren kann:</p>
<pre><code class="language-cpp">template&lt;class F, class G&gt;
auto twice(F f) {return [](G x){return f(f(x));};}
</code></pre>
<p>Das lässt sich so natürlich nicht kompilieren, aber ich denke, die Idee ist klar: Ich möchte später sowas schreiben können wie</p>
<pre><code class="language-cpp">double t = twice(sqrt)(16);
</code></pre>
<p>Das Ergebnis wäre dann sqrt(sqrt(16)) = 2.</p>
<p>Wie könnte ich so eine Funktion twice schreiben (ob mit Lambdas oder nicht ist mir egal).</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/313272/funktionale-spielereien</link><generator>RSS for Node</generator><lastBuildDate>Sun, 02 Aug 2026 07:49:53 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/313272.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 25 Jan 2013 21:19:27 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 21:19:40 GMT]]></title><description><![CDATA[<p>Ich bin gerade dabei, ein wenig mit lambda-Ausdrücken rumzuspielen und wollte mal wissen, ob man sowas hier mit C++ realisieren kann:</p>
<pre><code class="language-cpp">template&lt;class F, class G&gt;
auto twice(F f) {return [](G x){return f(f(x));};}
</code></pre>
<p>Das lässt sich so natürlich nicht kompilieren, aber ich denke, die Idee ist klar: Ich möchte später sowas schreiben können wie</p>
<pre><code class="language-cpp">double t = twice(sqrt)(16);
</code></pre>
<p>Das Ergebnis wäre dann sqrt(sqrt(16)) = 2.</p>
<p>Wie könnte ich so eine Funktion twice schreiben (ob mit Lambdas oder nicht ist mir egal).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293507</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293507</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Fri, 25 Jan 2013 21:19:40 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 21:40:59 GMT]]></title><description><![CDATA[<pre><code>template &lt;typename F, typename T&gt;
T twice(F f, T val) {return f(f(val));}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2293514</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293514</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Fri, 25 Jan 2013 21:40:59 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 21:52:23 GMT]]></title><description><![CDATA[<p>Ist zwar nicht ganz so toll funktionial, scheint mir aber lesbarer und nützlicher:</p>
<pre><code>template &lt;unsigned N&gt;
struct apply
{
	template &lt;typename T, typename F&gt;
	auto operator () (T v, F f) const -&gt; decltype(f(apply&lt;N - 1&gt;()(v, f)))
	{
		return f(apply&lt;N - 1&gt;()(v, f));
	}
};

template &lt;&gt;
struct apply&lt;0&gt;
{
	template &lt;typename T, typename F&gt;
	T operator () (T v, F) const
	{
		return v;
	}
};

int main()
{
	apply&lt;5&gt; ap;
	double t = ap(2.0, [] (double d) { return d * 2.0; });
	std::cout &lt;&lt; t &lt;&lt; '\n';
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2293516</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293516</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Fri, 25 Jan 2013 21:52:23 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 22:08:57 GMT]]></title><description><![CDATA[<p>Ja, das geht. Ich hätte aber gerne so eine funktionale Variante, mit der ich auch</p>
<pre><code class="language-cpp">double t = twice(twice)(sqrt)(65536); // 4-facher sqrt-Aufruf
</code></pre>
<p>bzw. was Äquivalents schreiben kann. Oder auch sowas:</p>
<pre><code class="language-cpp">double t = twice(twice)(twice)(sqrt)(65536); // 16-facher sqrt-Aufruf
</code></pre>
<p>Möglicherweise müsste man noch mehr Klammern setzen, ka, ob C++ sowas zulässt, aber wenn man den Term von links nach recht auswertet, ist es eindeutig, was gemeint ist.</p>
<p>@cooky: ja, das ist auch ganz nice. Aber ich möchte ineinander schachteln können. Ich brauche also eine Funktion, die eine Funktion auf eine andere Funktion abbildet. Lesbarkeit ist nicht so wichtig, es geht hier nur ums Ausprobieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293517</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293517</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Fri, 25 Jan 2013 22:08:57 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 22:09:14 GMT]]></title><description><![CDATA[<p>So könnte man anfangen:</p>
<pre><code>template&lt;class G, class F&gt;
auto twice(F f) -&gt; std::function&lt;typename std::result_of&lt;F(G)&gt;::type(G)&gt; {return [=](G x){return f(f(x));};}
</code></pre>
<pre><code>auto mysqrt=[](double v) {return std::sqrt(v);}; //std::sqrt ist mehrfach überladen
std::cout &lt;&lt; twice&lt;double&gt;(mysqrt)(65536) &lt;&lt; std::endl;
</code></pre>
<p>Die explizite Angabe des Parametertyps müsste sich auch noch wegzaubern lassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293521</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293521</guid><dc:creator><![CDATA[Athar]]></dc:creator><pubDate>Fri, 25 Jan 2013 22:09:14 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 22:19:49 GMT]]></title><description><![CDATA[<p>Was für einen Parametertyp müsste ich denn angeben, wenn ich &quot;twice&lt;...&gt;(twice&lt;double&gt;)(mysqrt)(65536)&quot; auswerten möchte?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293526</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Fri, 25 Jan 2013 22:19:49 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 22:25:39 GMT]]></title><description><![CDATA[<p>Wurde das nicht schon alles mal gemacht, also in einer Bibliothek der Kommaoperator ueberladen um Verkettung a la Haskell zu erreichen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293527</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293527</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Fri, 25 Jan 2013 22:25:39 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 22:28:42 GMT]]></title><description><![CDATA[<p>Ramanujan schrieb:</p>
<blockquote>
<p>Was für einen Parametertyp müsste ich denn angeben, wenn ich &quot;twice&lt;...&gt;(twice&lt;double&gt;)(mysqrt)(65536)&quot; auswerten möchte?</p>
</blockquote>
<p>Anzugeben ist jeweils der Parametertyp, den die erzeugte Funktion entgegennehmen soll, also idealerweise:</p>
<pre><code>twice&lt;double&gt;(twice&lt;double&gt;(mysqrt))(65536)
</code></pre>
<p>Darf aber auch ein anderer Typ sein, der sich implizit nach double konvertieren lässt, z.B. int.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293529</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293529</guid><dc:creator><![CDATA[Athar]]></dc:creator><pubDate>Fri, 25 Jan 2013 22:28:42 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 22:47:07 GMT]]></title><description><![CDATA[<p>Ich möchte aber nicht</p>
<pre><code class="language-cpp">twice&lt;double&gt;(twice&lt;double&gt;(mysqrt))(65536)
</code></pre>
<p>sondern</p>
<pre><code class="language-cpp">(twice&lt;double&gt;(twice&lt;double&gt;))(mysqrt)(65536)
</code></pre>
<p>die erzeuge Funktion von (dem ersten) twice nimmt als Typ eine Funktion von double nach double entgegen. Wie gebe ich das nun als Parameter an?</p>
<p>(Bei diesem Beispiel sind beide Ausdrücke äquivalent, bei 3 twice ist das aber nicht mehr der Fall)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293536</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293536</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Fri, 25 Jan 2013 22:47:07 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Fri, 25 Jan 2013 23:15:00 GMT]]></title><description><![CDATA[<p>Ich denke nicht, dass das möglich ist. Der Ausdruck (twice&lt;&gt;()) müsste irgendeinen Typen haben, kann er aber nicht, weil man ja alles Aufrufbare benutzen können soll. Man könnte sich uU auf Funktionspointer beschränken, aber wozu dann überhaupt diese Syntax, wenn man nicht &quot;wirklich&quot; funktional programmieren kann? Abgesehen davon finde ich meine Variante von oben eh hübscher, und als Funktions-Objekt kann es auch herhalten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293542</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Fri, 25 Jan 2013 23:15:00 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Sat, 26 Jan 2013 00:47:09 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Abgesehen davon finde ich meine Variante von oben eh hübscher, und als Funktions-Objekt kann es auch herhalten.</p>
</blockquote>
<p>Sehe ich nicht so, dein Ding ist absolut unhandlich. Hier ein besserer Ansatz:</p>
<pre><code class="language-cpp">template &lt;typename F&gt;
struct twice_ {
  twice_(F f) : f(std::move(f)) {}
  F f;
  template &lt;typename T, typename R = decltype(f(f(std::declval&lt;T&gt;())))&gt;
  R operator () (T x) { return f(f(x)); }
};
template &lt;typename F&gt; twice_&lt;F&gt; twice(F f) { return twice_&lt;F&gt;(std::move(f)); }

int main()
{
  auto square = [](double x){return x*x;};
  std::transform(std::istream_iterator&lt;double&gt;(std::cin),
                 std::istream_iterator&lt;double&gt;{},
                 std::ostream_iterator&lt;double&gt;(std::cout, &quot;\n&quot;),
                 twice(twice(square))); // 4-facher square-Aufruf, hoch 16               
}
</code></pre>
<p>Wie würde Zeile 16 mit deinem Ansatz lauten?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293553</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293553</guid><dc:creator><![CDATA[dingi]]></dc:creator><pubDate>Sat, 26 Jan 2013 00:47:09 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Sat, 26 Jan 2013 20:07:19 GMT]]></title><description><![CDATA[<p>Ja, aber auch bei deiner Lösung kann man</p>
<pre><code class="language-cpp">twice(twice)(square)(2)
</code></pre>
<p>nicht schreiben. Ich denke mal, dass man sowas auch nicht mit C++ machen kann. Man bedenke, dass das linke twice mathematisch gesehen vom Typ<br />
((d -&gt; d) -&gt; (d -&gt; d)) -&gt; ((d -&gt; d) -&gt; (d -&gt; d))<br />
ist, wobei d für double steht. Bei 3 twice verdoppelt sich nochmal die Länge des Typs.</p>
<p>Es ging hier übrigens nicht um eine hübsche Lösung, sondern um die Machbarkeit allgemein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293736</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293736</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Sat, 26 Jan 2013 20:07:19 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Sat, 26 Jan 2013 21:25:53 GMT]]></title><description><![CDATA[<p>Das Problem ist, dass twice auf die Art keine Funktion ist, sondern eine Funktionsvorlage -- insbesondere, dass twice kein Objekt ist. Das lässt sich umgehen, aber mit Lambdas kommt man da (noch?) nicht weit.</p>
<p>Ich stelle mir das grundsätzlich etwa so vor:</p>
<pre><code class="language-cpp">#include &lt;cmath&gt;
#include &lt;iostream&gt;

template&lt;typename F&gt;
struct apply_twice_type {
  F func_;

  apply_twice_type(F f) : func_(f) { }

  template&lt;typename P&gt;
  auto operator()(P p) const -&gt; decltype(func_(func_(p))) { return func_(func_(p)); }
};

struct twice_type {
  template&lt;typename F&gt;
  apply_twice_type&lt;F&gt; operator()(F f) const { return apply_twice_type&lt;F&gt;(f); }
} const twice; // &lt;-- twice jetzt ein Objekt

int main() {
  double (*sq)(double) = std::sqrt; // Überladene Funktion, Auflösung notwendig.
  std::cout &lt;&lt; twice(twice)(sq)(16.0) &lt;&lt; '\n';
}
</code></pre>
<p>Es gibt Vorschläge für den nächsten Standard, die Lambdas mit generischem operator() vorsehen, aber das ist wohl noch eine Weile hin. Wenn das kommt, dann könnte man diesen Mechanismus mit Lambdas auch nachbauen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293754</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293754</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Sat, 26 Jan 2013 21:25:53 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Sat, 26 Jan 2013 21:42:30 GMT]]></title><description><![CDATA[<p>Cool, es geht ja doch. Thx.</p>
<p>Traumhaft, wie lange es dauert, das hier zu kompilieren:</p>
<pre><code class="language-cpp">int main() { 
   auto succ = [](int x){return x+1;};
   std::cout &lt;&lt; twice(twice)(twice)(twice)(succ)(0) &lt;&lt; '\n'; 
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2293760</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293760</guid><dc:creator><![CDATA[Ramanujan]]></dc:creator><pubDate>Sat, 26 Jan 2013 21:42:30 GMT</pubDate></item><item><title><![CDATA[Reply to Funktionale Spielereien on Sat, 26 Jan 2013 22:12:33 GMT]]></title><description><![CDATA[<p>@seldon<br />
Beim Raum, das hast du schön gemacht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2293769</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2293769</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 26 Jan 2013 22:12:33 GMT</pubDate></item></channel></rss>