<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Clinton,<div class=""><br class=""></div><div class="">Sadly, GHC does not support what you want. I don't really have much more to add to your post, which accurately describes the problem and correctly describes why we can't have one compiled function that works at multiple representations.</div><div class=""><br class=""></div><div class="">The canonical ticket for this kind of feature is <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/14917" class="">https://gitlab.haskell.org/ghc/ghc/-/issues/14917</a>. I, for one, would welcome further improvements in this direction, but I don't have the capacity to drive them myself.</div><div class=""><br class=""></div><div class="">Richard<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 21, 2022, at 10:09 AM, Clinton Mead <<a href="mailto:clintonmead@gmail.com" class="">clintonmead@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi All<br class=""><br class="">I can make a list of unboxed ints like below:<br class=""><br class=""><font face="monospace" class="">{-# LANGUAGE MagicHash #-}<br class=""><br class="">import GHC.Exts (Int#, Float#) <br class=""><br class="">data IntList = IntTail | IntNode Int# IntList<br class=""><br class="">intListLength :: IntList -> Int<br class="">intListLength IntTail = 0<br class="">intListLength (IntNode _ rest) = 1 + intListLength rest </font><br class=""><div class=""><br class="">I can then make a list of unboxed floats similarly:<br class=""><br class=""><font face="monospace" class="">data FloatList = FloatTail | FloatNode Int# FloatList<br class=""><br class="">floatListLength :: FloatList -> Int<br class="">floatListLength FloatTail = 0<br class="">floatListLength (FloatNode _ rest) = 1 + floatListLength rest </font><br class=""><br class="">But as you can see, this is getting a bit copy-pasta, which is not good. So instead, lets try this:<br class=""><br class=""><font face="monospace" class="">newtype GeneralList (a :: l) = Tail | Node a (GeneralList a)</font><br class=""><br class="">This is not allowed here, I believe because `GeneralList` is expected to have one representation for all `a`, instead of a representation which depends on `a`. This is so that if one writes a function:<br class=""><br class=""><font face="monospace" class="">generalListLength :: GeneralList a -> Int<br class="">generalListLength Tail = 0<br class="">generalListLength (Node _ rest) = 1 + generalListLength rest</font><br class=""><br class="">You can't actually compile this into one function, because the relative location of the "next" pointer can change based on the size of `a` (assuming `a` is stored first).<br class=""><br class="">However, I can achieve what I want with copy pasting or Template Haskell hackery. <br class=""><br class="">Is there a way to get GHC to do the copy pasting for me? Or do I have to make a choice between extra runtime indirection and avoiding ugly code or having ugly code but avoiding the runtime indirection? A representation polymorphic list here is something that languages like C++, Rust, and even C# will handle happily, so Haskell seems behind here unless I'm missing something, </div></div>
_______________________________________________<br class="">Glasgow-haskell-users mailing list<br class=""><a href="mailto:Glasgow-haskell-users@haskell.org" class="">Glasgow-haskell-users@haskell.org</a><br class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users<br class=""></div></blockquote></div><br class=""></div></body></html>