<div dir="auto"><div>The current NFData instance in dlist is the best you can do. seq on a function (very) rarely does what you want. The instance the package defines guarantees that the DList represents a list that can be reduced to normal form. The semantics are right. Efficiency-wise, it's lousy, but there's no way to fix it (without changing the underlying representation).</div><div dir="auto"><div class="gmail_extra" dir="auto"><br><div class="gmail_quote">On Jun 13, 2017 11:26 PM, "Dr.Koster" <<a href="mailto:drkoster@qq.com">drkoster@qq.com</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="quoted-text"><div><br>> What can that offer in the way of instances? Well, it's clearly not a<br>> Functor, so it's certainly not Applicative, Monad, MonadPlus, or<br>> Traversable. Ouch. There's no way to write matching Read and Show<br>> instances, so you're stuck picking just one. Similarly, IsList and<br>> IsString aren't guaranteed to round-trip properly. NFData is utterly<br>> absurd, of course. So what's left? Foldable, Monoid, and either Read<br>> or Show. The Foldable instance doesn't even interact nicely with the<br>> Monoid instance: there's no guarantee that  foldMap f xs <> foldMap f<br>> ys = foldMap f (xs <> ys). So there's pretty much *nothing going on<br>> here*. DList x just doesn't have much more to offer than Endo [x]. We<br>> already have Endo; ergo, we don't need DList.</div><div><br></div></div><div>I think that's OK:</div><div><br></div><div>1) If we're concerning those inefficient instances(My understanding is those defined using `toList`, such as `<span style="white-space:pre-wrap">Foldable` and `Functor`</span>), we can just don't add them. </div><div>2) Even `type DList a = Endo [a]` is OK, what i'm asking is CPSed operations (such as cons, replicate...) working on this type, not those instances. </div><div><br></div><div>BTW. Isn't current `<span style="white-space:pre-wrap">NFData`instance in dlist package problematic? We should directly `seq` the function IMHO.</span></div><div><span style="white-space:pre-wrap"><br></span></div><div></div></div><div><div><br></div><div><br></div><div style="font-size:12px;font-family:Arial Narrow;padding:2px 0 2px 0">------------------ 原始邮件 ------<wbr>------------</div><div style="font-size:12px;background:#efefef;padding:8px"><div><b>发件人:</b> "David Feuer";<<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>><wbr>;</div><div><b>发送时间:</b> 2017年6月6日(星期二) 中午11:09</div><div class="quoted-text"><div><b>收件人:</b> "Dr.Koster"<<a href="mailto:drkoster@qq.com" target="_blank">drkoster@qq.<wbr>com</a>>; </div><div><b>抄送:</b> "libraries"<<a href="mailto:libraries@haskell.org" target="_blank">libraries@<wbr>haskell.org</a>>; </div><div><b>主题:</b> Re: Add DList to base</div></div></div><div><br></div><div class="elided-text">I'm -1 on this. For an abstract DList-style list builder, there's the<br>dlist package, which you shouldn't fear depending on (its only<br>dependencies are base and deepseq, both of which are GHC boot<br>packages). The dlist package defines a DList that's an instance of<br>MonadPlus, Traversable, IsList, Ord, Read, Show, IsString, Monoid, and<br>NFData, and provides a variety of functions for working with them.<br>Many of the instances and functions are, inherently, absurdly<br>inefficient. This is because there's basically *nothing* you can do to<br>a DList directly except build one up with `.` and tear one down with<br>`apply`. DLists are extremely efficient precisely when GHC is able to<br>optimize them away altogether. As soon as that is not the case,<br>they're mediocre at best.<br><br>Now suppose you want a non-abstract DList type (with the constructor exposed).<br><br>newtype DList a = DL { unDL :: [a] -> [a] }<br><br>What can that offer in the way of instances? Well, it's clearly not a<br>Functor, so it's certainly not Applicative, Monad, MonadPlus, or<br>Traversable. Ouch. There's no way to write matching Read and Show<br>instances, so you're stuck picking just one. Similarly, IsList and<br>IsString aren't guaranteed to round-trip properly. NFData is utterly<br>absurd, of course. So what's left? Foldable, Monoid, and either Read<br>or Show. The Foldable instance doesn't even interact nicely with the<br>Monoid instance: there's no guarantee that  foldMap f xs <> foldMap f<br>ys = foldMap f (xs <> ys). So there's pretty much *nothing going on<br>here*. DList x just doesn't have much more to offer than Endo [x]. We<br>already have Endo; ergo, we don't need DList.<br><br>On Mon, Jun 5, 2017 at 3:58 AM, Dr.Koster <<a href="mailto:drkoster@qq.com" target="_blank">drkoster@qq.com</a>> wrote:<br>> Currently GHC already defined DList for internal use in serveral places.<br>> This data type is a nature choice when you need CPS your append, which is a<br>> common need. I think base should provide it.<br>><br>> Cheers~<br>> Winter<br>><br>> ______________________________<wbr>_________________<br>> Libraries mailing list<br>> <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br>><br></div></div></blockquote></div><br></div></div></div>