matrix-static: Wrapper around matrix that adds matrix sizes to the type-level

[ bsd3, library, math ] [ Propose Tags ]

Please see the README on GitHub at https://github.com/wchresta/matrix-static#readme


[Skip to Readme]
Versions [faq] 0.1, 0.1.1, 0.2
Change log ChangeLog.md
Dependencies base (>=4.9 && <4.12), deepseq, ghc-typelits-knownnat, ghc-typelits-natnormalise, matrix (>=0.3.5 && <0.4), semigroups, vector [details]
License BSD-3-Clause
Copyright 2018, Wanja Chresta
Author Wanja Chresta
Maintainer wanja.hs@chrummibei.ch
Revised Revision 1 made by phadej at Tue Oct 16 15:41:19 UTC 2018
Category Math
Home page https://github.com/wchresta/matrix-static#readme
Bug tracker https://github.com/wchresta/matrix-static/issues
Source repo head: git clone https://github.com/wchresta/matrix-static
Uploaded by wchresta at Wed Aug 29 06:24:10 UTC 2018
Distributions LTSHaskell:0.2, NixOS:0.2, Stackage:0.2
Downloads 438 total (65 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs uploaded by user
Build status unknown [no reports yet]

Modules

[Index]

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

For package maintainers and hackage trustees


Readme for matrix-static-0.1

[back to package description]

matrix-static

A static wrapper around the [https://hackage.haskell.org/package/matrix|matrix] library. It provides a data type Matrix m n a derived from matrix's Matrix a with additional information about the matix dimension m n as type-level Nat's.

(Almost) all functions provided by Data.Matrix are wrapped. These wrappers guarantee during compile time that the matrix dimension are correct. As such, runtime errors due to mismatching matrix dimensions are minimized. Also, some performance improvements are achieved by not having to do dimension checks during runtime.

Some functions take indices i as parameters (e.g. Matrix.Data.mapCol).

mapCol :: (Int -> a -> a) -> Int -> Matrix a -> Matrix a

For these, a decision has to be made. Either the runtime index i is kept at the runtime level, or it is moved to the type-level. If it remains at the run-time level, it is kept as a parameter but the correctness of the index cannot be guaranteed by the compiler (e.g. there will be an error if the index is -1). If it is moved to the type-level as a type-parameter, the compiler can guarantee the correctnes of the index, but it is not dependent on any values during runtime:

As such, Data.Matrix.Static.mapCol chooses to go the safe route and provide j as a type level parameter:

mapCol :: forall j m n a. (KnownNat j, KnownNat m, 1 <= j, j <= n)
       => (Int -> a -> a) -> Matrix m n a -> Matrix m n a

Since it might be important to be able to provide mapCol with a run-time index, the following function is also provided:

mapColUnsafe :: (Int -> a -> a) -> Int -> Matrix m n a -> Matrix m n a

Of course, it will cause an error if the given index does not match the matrix dimensions. In some cases, the result of a run-time variant of a function is wrapped in Maybe and thus becomes safe. In general, all functions in the library that do not guarantee that no error will be thrown have the postfix Unsafe.

Usage example

Note, if you want to provide type-level paramters similar to run-time parameters, make sure to use the DataKinds and TypeApplicatios extensions. Then, you can give type-level parameters using @ as demonstrated instead of giving the full type.

>>> :set -XDataKinds -XTypeApplications
>>> fromList [1..9] :: Maybe (Matrix 3 3 Int)
Just ┌       ┐
│ 1 2 3 │
│ 4 5 6 │
│ 7 8 9 │
└       ┘
>>> fromList [1..8] :: Maybe (Matrix 3 3 Int)
Nothing

>>> fromJust $ fromList [1..8] :: Matrix 2 4 Int
┌     ┐
│ 1 2 │
│ 3 4 │
│ 5 6 │
│ 7 8 │
└     ┘

>>> a = fromListUnsafe @4 @4 [1..16]
>>> b = fromListUnsafe @4 @2 [4..12]
>>> b .* a

<interactive>:6:6: error:
    * Couldn't match type `4' with `2'
      Expected type: Matrix 2 4 a
        Actual type: Matrix 4 4 a
    * In the second argument of `(.*)', namely `a'
      In the expression: b .* a
      In an equation for `it': it = b .* a
>>> a .* b
┌         ┐
│  80  90 │
│ 192 218 │
│ 304 346 │
│ 416 474 │
└         ┘