<div dir="ltr">+1, and +1 for exposing the constructor.  If we implemented Dynamic from scratch today this is what it would look like, so let's get rid of the old cruft!<div><br></div><div>John L.</div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Mon, Aug 25, 2014 at 11:15 PM, Edward Kmett <span dir="ltr"><<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div><div>I'd like to propose a cleanup to the API of <font face="courier new, monospace">Data.Dynamic</font>.</div></div><div><br></div><div>By way of (partial) motivation, a couple of years back Lennart posed <a href="http://stackoverflow.com/questions/10889682/how-to-apply-a-polymorphic-function-to-a-dynamic-value/10890414#comment39759480_10890414" target="_blank">a question on stackoverflow</a> about how to use <font face="courier new, monospace">Dynamic</font> to implement<br>

</div><div><br></div><font face="courier new, monospace">apD :: forall f. Typeable1 f => </font><div><font face="courier new, monospace">  (forall a. a -> f a) -> Dynamic -> Dynamic</font><div><br></div><div>
<div>
<br></div><div>At the time, I offered a solution that is no longer applicable in a world with polykinded <font face="courier new, monospace">Typeable</font>.</div><div><br></div><div>But, if we change the definition of <font face="courier new, monospace">Data.Dynamic</font> to</div>

<div><br></div><div><div><font face="courier new, monospace">data Dynamic where</font></div><div><font face="courier new, monospace">  Dynamic :: Typeable a => a -> Dynamic</font></div></div><div><br></div><div>from its current magic implementation in terms of <font face="courier new, monospace">unsafeCoerce</font> and a manually held <font face="courier new, monospace">typeRep</font>, then </div>

<div><br></div><div><font face="courier new, monospace">fromDynamic</font> becomes a trivial application of <font face="courier new, monospace">Data.Typeable.cast</font> and <font face="courier new, monospace">dynApply</font> becomes easier, </div>

<div><br></div><div><div>This would enable us to implement <font face="courier new, monospace">Data.Dynamic</font> with its full constructor exposed without losing safety.</div></div><div><br></div><div>In lieu of supplying the constructor, we could offer a form of<br>

</div><div><br></div><div><font face="courier new, monospace">withDyn :: Dynamic -> (forall a. Typeable a => a -> r) -> r</font></div><div><br></div><div>but I'd rather expose the constructor rather than needlessly Church encode as the kind of code/user that needs this is the kind that would bemoan needless performance barriers in the name of nebulous encapsulation benefits.</div>

<div><br></div><div>Now it becomes possible to write code that does polymorphic things underneath the <font face="courier new, monospace">Dynamic</font> wrapper, such as Lennart's example once more, but now in a principled way.</div>

</div></div><div><br></div><div>Discusssion Period: 2 Weeks</div><div><br></div><div><b>tl;dr</b> polykinded <font face="courier new, monospace">Typeable</font> took away some power from the users of <font face="courier new, monospace">Data.Dynamic</font>, which we can give back in a more principled way, simplifying the API as a result.</div>
<span class="HOEnZb"><font color="#888888">
<div><br></div><div>-Edward</div></font></span></div>
<br>_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/libraries" target="_blank">http://www.haskell.org/mailman/listinfo/libraries</a><br>
<br></blockquote></div><br></div>