<h2 style="font-weight: normal;"><font size="2">Hi All,</font></h2><h2 style="font-weight: normal;"><font size="2">Inspired by Oleg&#39;s &quot;Eliminating Array Bound Checking through Non-dependent types&quot;&nbsp;</font><font size="2">
 <a href="http://okmij.org/ftp/Haskell/types.html#branding">http://okmij.org/ftp/Haskell/types.html#branding</a>,</font></h2>I am attempting to write code that will receive an array from C land and convert it to a type safe representation.&nbsp; The array could have n dimensions where n &gt; 2.&nbsp; I receive the number of dimensions as a list of Ints [Int].&nbsp; To do type-safe programming I need to convert this to a type level representation.&nbsp; Using CPS (thanks to ski on #haskell) I can convert an Int to the type level.&nbsp; But I have found it impossible to insert this type-level Digits representation into an HList.
<br><br>In Oleg&#39;s examples with vectors he types in by hand the data whose type represents the size of the vector:<br><br>sample_v = listVec (D2 Sz) [True,False]<br><br>where (D2 Sz) is the size of the vector and the type is:
<br><br>ArbPrecDecT&gt; :t sample_v<br>Vec (D2 Sz) Bool<br><br>In a real program we can&#39;t expect the programmer to type in the size of the data, it needs to be done programmatically, and this is where I am stuck.<br><br>
Could someone please point me in the right direction, or explain why what I&#39;m trying to do won&#39;t work?&nbsp; Basically I&#39;m looking for a function<br>int2typelevel :: (HList l) :: [Int] -&gt; l<br><br>I thought that this would work because HLists can have elements of different types and I can already (modulo CPS) convert an Int to it&#39;s Digits type level representation.
<br><br>One approach which won&#39;t work is existentially wrapping the result of num2digits in a GADT, because this hides the type from the type-checker and then can&#39;t be used for bounds checking.<br><br>Here is an example of what I want to be able to do:
<br><br>add :: Equal size1 size2 =&gt; Array size1 idx -&gt; Array size2 idx -&gt; Array size1 idx<br><br>for example:<br><br>data Array size idx = Array size (MArray idx Double)<br><br>add (Array (DCons (D1 (D2 Sz)) (DCons (D3 Sz) DNil)) (12,3)) (Array (DCons (D1 (D2 Sz)) (DCons (D3 Sz) DNil)) (12,3))
<br><br>the sizes are statically checked and I don&#39;t have to do runtime checking on the idx.<br><br>This message is a literate source file.&nbsp; The commented out function at the end illustrates the problem.<br><br>Thanks,
<br><br>Vivian<br><br>&gt;{-# OPTIONS -fglasgow-exts #-}<br>&gt;<br>&gt;-- copied from <a href="http://okmij.org/ftp/Haskell/number-parameterized-types.html">http://okmij.org/ftp/Haskell/number-parameterized-types.html</a>
<br>&gt;<br>&gt;module Digits where<br>&gt;<br>&gt;data D0 a = D0 a deriving(Eq,Read,Show)<br>&gt;data D1 a = D1 a deriving(Eq,Read,Show)<br>&gt;data D2 a = D2 a deriving(Eq,Read,Show)<br>&gt;data D3 a = D3 a deriving(Eq,Read,Show)
<br>&gt;data D4 a = D4 a deriving(Eq,Read,Show)<br>&gt;data D5 a = D5 a deriving(Eq,Read,Show)<br>&gt;data D6 a = D6 a deriving(Eq,Read,Show)<br>&gt;data D7 a = D7 a deriving(Eq,Read,Show)<br>&gt;data D8 a = D8 a deriving(Eq,Read,Show)
<br>&gt;data D9 a = D9 a deriving(Eq,Read,Show)<br>&gt;<br>&gt;class Digits ds where&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -- class of digit sequences<br>&gt;&nbsp;&nbsp;&nbsp; ds2num:: (Num a) =&gt; ds -&gt; a -&gt; a&nbsp;&nbsp;&nbsp;&nbsp; -- CPS style<br>&gt;&nbsp;&nbsp; <br>&gt;data Sz = Sz&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -- zero size (or the Nil of the sequence)
<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deriving(Eq,Read,Show)<br>&gt;<br>&gt;instance Digits Sz where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num _ acc = acc<br>&gt;&nbsp;&nbsp;&nbsp; <br>&gt;instance (Digits ds) =&gt; Digits (D0 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc)
<br>&gt;instance (Digits ds) =&gt; Digits (D1 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 1)<br>&gt;instance (Digits ds) =&gt; Digits (D2 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 2)
<br>&gt;instance (Digits ds) =&gt; Digits (D3 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 3)<br>&gt;instance (Digits ds) =&gt; Digits (D4 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 4)
<br>&gt;instance (Digits ds) =&gt; Digits (D5 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 5)<br>&gt;instance (Digits ds) =&gt; Digits (D6 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 6)
<br>&gt;instance (Digits ds) =&gt; Digits (D7 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 7)<br>&gt;instance (Digits ds) =&gt; Digits (D8 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 8)
<br>&gt;instance (Digits ds) =&gt; Digits (D9 ds) where<br>&gt;&nbsp;&nbsp;&nbsp; ds2num dds acc = ds2num (t22 dds) (10*acc + 9)<br>&gt; <br>&gt;t22::(f x)&nbsp;&nbsp; -&gt; x; t22 = undefined<br>&gt;<br>&gt;-- Class of non-negative numbers<br>&gt;-- This is a restriction on Digits. It is not possible to make
<br>&gt;-- such a restriction in SML.<br>&gt;class {- (Digits c) =&gt; -} Card c where<br>&gt;&nbsp;&nbsp;&nbsp; c2num:: (Num a) =&gt; c -&gt; a<br>&gt;&nbsp;&nbsp;&nbsp; <br>&gt;instance Card Sz where c2num c = ds2num c 0<br>&gt;--instance (NonZeroDigit d,Digits (d ds)) =&gt; Card (Sz (d ds)) where
<br>&gt;instance (Digits ds) =&gt; Card (D1 ds) where c2num c = ds2num c 0<br>&gt;instance (Digits ds) =&gt; Card (D2 ds) where c2num c = ds2num c 0<br>&gt;instance (Digits ds) =&gt; Card (D3 ds) where c2num c = ds2num c 0
<br>&gt;instance (Digits ds) =&gt; Card (D4 ds) where c2num c = ds2num c 0<br>&gt;instance (Digits ds) =&gt; Card (D5 ds) where c2num c = ds2num c 0<br>&gt;instance (Digits ds) =&gt; Card (D6 ds) where c2num c = ds2num c 0
<br>&gt;instance (Digits ds) =&gt; Card (D7 ds) where c2num c = ds2num c 0<br>&gt;instance (Digits ds) =&gt; Card (D8 ds) where c2num c = ds2num c 0<br>&gt;instance (Digits ds) =&gt; Card (D9 ds) where c2num c = ds2num c 0
<br>&gt;<br>&gt;-- Support for &quot;generic&quot; cards<br>&gt;-- We introduce a data constructor CardC_unused merely for the sake of<br>&gt;-- Haskell98. With the GHC extension, we can simply omit the data<br>&gt;-- constructor and keep the type CardC purely abstract and phantom.
<br>&gt;data CardC c1 c2 = CardC_unused<br>&gt;<br>&gt;cardc:: (Card c1, Card c2) =&gt; c1 -&gt; c2 -&gt; CardC c1 c2<br>&gt;cardc = undefined<br>&gt;cardc1::CardC c1 c2 -&gt; c1; cardc1 = undefined<br>&gt;cardc2::CardC c1 c2 -&gt; c2; cardc2 = undefined
<br>&gt;<br>&gt;instance (Card c1, Card c2) =&gt; Card (CardC c1 c2) where<br>&gt;&nbsp;&nbsp;&nbsp; c2num c12 = c2num (cardc1 c12) + c2num (cardc2 c12)<br>&gt;<br>&gt;-----------------------------------------------------------------------------
<br>&gt;-- make lists<br>&gt;<br>&gt;-- copied from HList: <a href="http://okmij.org/ftp/Haskell/types.html#HList">http://okmij.org/ftp/Haskell/types.html#HList</a><br>&gt;<br>&gt;data DNil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = DNil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deriving (Eq,Show,Read)
<br>&gt;data DCons e l = DCons e l deriving (Eq,Show,Read)<br>&gt;<br>&gt;class DList l<br>&gt;instance DList DNil<br>&gt;instance (Digits e, DList l) =&gt; DList (DCons e l)<br>&gt;<br>&gt;dNil :: DNil<br>&gt;dNil = DNil
<br>&gt;<br>&gt;dCons :: forall e. Digits e =&gt; (DList l =&gt; e -&gt; l -&gt; DCons e l)<br>&gt;dCons e l = DCons e l<br>&gt;<br>&gt;-- ^ Oleg<br>&gt;-----------------------------------------------------------------------------
<br>&gt;-- v Vivian<br>&gt;<br>&gt;-- CPS<br>&gt;num2digits :: (Integral a, Show a) =&gt; a -&gt; (forall ds. (Digits ds) =&gt; ds -&gt; o) -&gt; o<br>&gt;num2digits n = str2digits (show n) <br>&gt;<br>&gt;str2digits :: String -&gt; (forall ds. (Digits ds) =&gt; ds -&gt; o) -&gt; o
<br>&gt;str2digits [] k = k Sz<br>&gt;str2digits (&#39;0&#39; : ss) k = str2digits ss (\ds -&gt; k (D0 ds))<br>&gt;str2digits (&#39;1&#39; : ss) k = str2digits ss (\ds -&gt; k (D1 ds))<br>&gt;str2digits (&#39;2&#39; : ss) k = str2digits ss (\ds -&gt; k (D2 ds))
<br>&gt;str2digits (&#39;3&#39; : ss) k = str2digits ss (\ds -&gt; k (D3 ds))<br>&gt;str2digits (&#39;4&#39; : ss) k = str2digits ss (\ds -&gt; k (D4 ds))<br>&gt;str2digits (&#39;5&#39; : ss) k = str2digits ss (\ds -&gt; k (D5 ds))
<br>&gt;str2digits (&#39;6&#39; : ss) k = str2digits ss (\ds -&gt; k (D6 ds))<br>&gt;str2digits (&#39;7&#39; : ss) k = str2digits ss (\ds -&gt; k (D7 ds))<br>&gt;str2digits (&#39;8&#39; : ss) k = str2digits ss (\ds -&gt; k (D8 ds))
<br>&gt;str2digits (&#39;9&#39; : ss) k = str2digits ss (\ds -&gt; k (D9 ds))<br>&gt;<br>&gt;-----------------------------------------------------------------------------<br>&gt;<br>&gt;--test = num2str 10 (\x -&gt; dCons x dNil)
<br><br>