Hi Gregory,<br><br>What can i do with the list i get from join (TaggedList (Plus m n))? I can&#39;t use head or tail on it... Maybe something like:<br><br><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">shiftl :: TaggedList (Plus (SuccessorTo m) n) -&gt; TaggedList (SuccessorTo (Plus m n))<br>
</font><br>I&#39;m still not sure there&#39;s an actual case where it&#39;s useful... You could make a class of non-empty lists:<br><br><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">class NonEmpty n where<br>
  head :: TaggedList n b -&gt; b<br>  tail :: TaggedList n b -&gt; TaggedList (? n) b<br><br>instance NonEmpty (SuccessorTo a) where<br>  head = theOldHeadFunction<br>  tail    = ?<br><br>instance (NonEmpty m, NonEmpty m) =&gt; NonEmpty (Plus n m) where<br>
  head = Prelude.head . toList<br>  tail    = ?</font><br><br>All you need to do is invent a suitable predecessor type (including its NonEmpty instance) and do the magic for tail. :)<br><br><br>Also, what is UntaggedList used for, and how is it different from [].<br>
<br>/J<br><br><br><br><br>On 14 October 2010 04:17, Gregory Crosswhite &lt;<a href="mailto:gcross@phys.washington.edu">gcross@phys.washington.edu</a>&gt; wrote:<br>&gt;<br>&gt;  Hey everyone,<br>&gt;<br>&gt; I am pleased to announce the release of tagged-list version 1.0, a package which provides fixed-length lists that are tagged with a phantom type-level natural number corresponding to the length. The advantage of such lists is that you can make static guarantees about them, so that for example the function<br>
&gt;<br>&gt; addLists :: TaggedList n Int -&gt; TaggedList n Int -&gt; TaggedList n Int<br>&gt; ...<br>&gt;<br>&gt; which adds two lists is guaranteed to get two lists of the same length and to produce a list with the same length as the inputs. Some basic operations on these lists have been provided, including instances for Applicable, Traversable, etc. One of the more interesting of these operations is the &quot;join&quot; function&quot;,<br>
&gt;<br>&gt; join :: TaggedList m α → TaggedList n α → (TaggedList (Plus m n) α,TaggedList (Plus m n) β → (TaggedList m β,TaggedList n β))<br>&gt;<br>&gt; This function takes two lists and appends them, and returns not only the appended list but also a function that takes a list of the same length and splits it into two lists with the same lengths as the inputs; one way of interpreting the second parameter is that it provides a &quot;proof&quot; that a TaggedList of type TaggedList (Plus m n) β can be broken into lists of type TaggedList m β and TaggedList n β. This function is provided because I couldn&#39;t figure out how to make a general &quot;split&quot; function pass the type-checker, and fortunately I found that in practice I didn&#39;t need a general such function because I was usually taking a list that was the result of some operation applied to two lists I had earlier appended and breaking the result list into sublists the lengths of the original two lists.<br>
&gt;<br>&gt; I also provided functions to convert tagged lists to and from tuples, which can be useful at the times when the type-checker gets confused by your &quot;a :. b :. ... :. E&quot; expression and gives you obscure error messages.<br>
&gt;<br>&gt; Anyway, I hope that the community finds this package useful, and welcome any feedback that you all have to offer.<br>&gt;<br>&gt; Cheers,<br>&gt; Greg<br>&gt;<br>&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br>