Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is entirely possible in Haskell.</p> <p><strong>Statically checked dimensions</strong></p> <p>Haskell has arrays with <strong><a href="http://hackage.haskell.org/packages/archive/repa/2.0.0.3/doc/html/Data-Array-Repa-Shape.html" rel="noreferrer">statically checked dimensions</a></strong>, where the dimensions can be manipulated and checked statically, preventing indexing into the wrong dimension. Some examples:</p> <p>This will only work <a href="http://hackage.haskell.org/packages/archive/repa-algorithms/2.0.0.3/doc/html/Data-Array-Repa-Algorithms-Matrix.html" rel="noreferrer">on 2-D arrays</a>:</p> <pre><code>multiplyMM :: Array DIM2 Double -&gt; Array DIM2 Double -&gt; Array DIM2 Double </code></pre> <p>An example from <code>repa</code> should give you a sense. Here, taking a diagonal requires a 2D array, returns a 1D array of the same type.</p> <pre><code>diagonal :: Array DIM2 e -&gt; Array DIM1 e </code></pre> <p>or, from <a href="http://syntacticsalt.com/2011/02/13/getting-started-with-repa/" rel="noreferrer">Matt sottile's repa tutorial</a>, statically checked dimensions on a 3D matrix transform:</p> <pre><code>f :: Array DIM3 Double -&gt; Array DIM2 Double f u = let slabX = (Z:.All:.All:.(0::Int)) slabY = (Z:.All:.All:.(1::Int)) u' = (slice u slabX) * (slice u slabX) + (slice u slabY) * (slice u slabY) in R.map sqrt u' </code></pre> <p><strong>Statically checked units</strong></p> <p>Another example from outside of matrix programming: statically checked <strong><a href="http://hackage.haskell.org/package/dimensional" rel="noreferrer">units of dimension</a></strong>, making it a type error to confuse e.g. feet and meters, without doing the conversion.</p> <pre><code> Prelude&gt; 3 *~ foot + 1 *~ metre 1.9144 m </code></pre> <p>or for a whole suite of <a href="http://hackage.haskell.org/packages/archive/dimensional/0.9/doc/html/Numeric-Units-Dimensional-Quantities.html" rel="noreferrer">SI units and quanities</a>. </p> <p>E.g. can't add things of different dimension, such as volumes and lengths:</p> <pre><code>&gt; 1 *~ centi litre + 2 *~ inch Error: Expected type: Unit DVolume a1 Actual type: Unit DLength a0 </code></pre> <p>So, following <a href="http://www.cse.unsw.edu.au/~chak/papers/repa.pdf" rel="noreferrer">the <code>repa</code>-style array dimension types</a>, I'd suggest adding a <code>Base</code> phantom type parameter to your array type, and using that to distinguish between bases. In Haskell, the index <code>Dim</code> type argument gives the rank of the array (i.e. its shape), and you could do similarly.</p> <p>Or, if by base you mean some dimension on the units, using dimensional types.</p> <p>So, yep, this is almost a commodity technique in Haskell now, and there's some examples of designing with types like this to help you get started.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload