on master help sign in
31 files changed+1072−923
since splitsnapshots
unifiedsplit
.ghc.environment.x86_64-linux-8.6.5−17 .github/workflows/ci.yml+43 .gitignore+54−2 .travis.yml+47 CHANGELOG.md+17 ChangeLog.md−3 LICENSE+17−26 README.md+34−30 Setup.hs−2 app/Main.hs−7 appveyor.yml+34 app/Benchmarks.hs → benchmark/Main.hs+11−13 hackage.sh−10 laop.cabal+89 package.yaml−57 src/LAoP/Dist.hs+2−2 src/LAoP/Dist/Internal.hs+44−43 src/LAoP/Matrix/Internal.hs+174−211 src/LAoP/Matrix/Nat.hs+68−80 src/LAoP/Matrix/Type.hs+143−124 src/LAoP/Relation.hs+3−4 src/LAoP/Relation/Internal.hs+211−200 src/LAoP/Utils.hs+4−1 src/LAoP/Utils/Internal.hs+28−2 stack-8.8.3.yaml+1 stack.yaml+1−66 stack.yaml.lock+4−4 app/Quantum.hs → test/Examples/Quantum.hs+6−4 app/Examples.hs → test/Examples/Readme.hs+25−10 app/Spreadsheets.hs → test/Examples/Spreadsheets.hs+5−4 test/Spec.hs+7−1
.ghc.environment.x86_64-linux-8.6.5deleted−17
@@ -1,17 +0,0 @@
1−-- This is a GHC environment file written by cabal. This means you can
2−-- run ghc or ghci and get the environment of the project as a whole.
3−-- But you still need to use cabal repl $target to get the environment
4−-- of specific components (libs, exes, tests etc) because each one can
5−-- have its own source dirs, cpp flags etc.
6−--
7−clear-package-db
8−global-package-db
9−package-db /home/bolt/.cabal/store/ghc-8.6.5/package.db
10−package-db packagedb/ghc-8.6.5
11−package-id laop-0.1.0.0-inplace
12−package-id base-4.12.0.0
13−package-id ghc-prim-0.5.3
14−package-id rts
15−package-id integer-gmp-1.0.2.0
16−package-id deepseq-1.4.4.0
17−package-id array-0.5.3.0
.github/workflows/ci.ymlnew file+43
@@ -0,0 +1,43 @@
1+name: CI
2+
3+# Trigger the workflow on push or pull request, but only for the master branch
4+on:
5+ pull_request:
6+ push:
7+ branches: [master]
8+
9+jobs:
10+ build:
11+ name: ghc ${{ matrix.ghc }}
12+ runs-on: ubuntu-16.04
13+ strategy:
14+ matrix:
15+ cabal: ["3.0"]
16+ ghc:
17+ - "8.6.5"
18+ - "8.8.3"
19+
20+ steps:
21+ - uses: actions/checkout@v2
22+ if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
23+
24+ - uses: actions/setup-haskell@v1
25+ name: Setup Haskell
26+ with:
27+ ghc-version: ${{ matrix.ghc }}
28+ cabal-version: ${{ matrix.cabal }}
29+
30+ - uses: actions/cache@v1
31+ name: Cache ~/.cabal/store
32+ with:
33+ path: ~/.cabal/store
34+ key: ${{ runner.os }}-${{ matrix.ghc }}-cabal
35+
36+ - name: Build
37+ run: |
38+ cabal v2-update
39+ cabal v2-build --enable-tests --enable-benchmarks
40+
41+ - name: Test
42+ run: |
43+ cabal v2-test --enable-tests
.gitignore+54−2
@@ -1,3 +1,55 @@
1+### Haskell
2+dist
3+dist-*
4+cabal-dev
5+*.o
6+*.hi
7+*.chi
8+*.chs.h
9+*.dyn_o
10+*.dyn_hi
11+*.prof
12+*.aux
13+*.hp
14+*.eventlog
15+.virtualenv
16+.hsenv
17+.hpc
18+.cabal-sandbox/
19+cabal.sandbox.config
20+cabal.config
21+cabal.project.local
22+.ghc.environment.*
23+.HTF/
24+# Stack
125.stack-work/
2−laop.cabal
3−*~
26+stack.yaml.lock
27+
28+### IDE/support
29+# Vim
30+[._]*.s[a-v][a-z]
31+[._]*.sw[a-p]
32+[._]s[a-v][a-z]
33+[._]sw[a-p]
34+*~
35+tags
36+
37+# IntellijIDEA
38+.idea/
39+.ideaHaskellLib/
40+*.iml
41+
42+# Atom
43+.haskell-ghc-mod.json
44+
45+# VS
46+.vscode/
47+
48+# Emacs
49+*#
50+.dir-locals.el
51+TAGS
52+
53+# other
54+.DS_Store
55+hackage.sh
.travis.ymlnew file+47
@@ -0,0 +1,47 @@
1+sudo: true
2+language: haskell
3+
4+git:
5+ depth: 5
6+
7+cabal: "3.0"
8+
9+cache:
10+ directories:
11+ - "$HOME/.cabal/store"
12+ - "$HOME/.stack"
13+ - "$TRAVIS_BUILD_DIR/.stack-work"
14+
15+matrix:
16+ include:
17+ - ghc: 8.6.5
18+ - ghc: 8.8.3
19+
20+ - ghc: 8.8.3
21+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack-8.8.3.yaml"
22+
23+ - ghc: 8.6.5
24+ env: STACK_YAML="$TRAVIS_BUILD_DIR/stack.yaml"
25+
26+
27+install:
28+ - |
29+ if [ -z "$STACK_YAML" ]; then
30+ cabal v2-update
31+ cabal v2-build --enable-tests --enable-benchmarks
32+ else
33+ curl -sSL https://get.haskellstack.org/ | sh
34+ stack --version
35+ stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks
36+ fi
37+
38+script:
39+ - |
40+ if [ -z "$STACK_YAML" ]; then
41+ cabal v2-test --enable-tests
42+ else
43+ stack test --system-ghc
44+ fi
45+
46+notifications:
47+ email: false
CHANGELOG.mdnew file+17
@@ -0,0 +1,17 @@
1+# Changelog
2+
3+`laop` uses [PVP Versioning][1].
4+The changelog is available [on GitHub][2].
5+
6+## 0.1.1.1
7+
8+* Bump base version to work with cabal
9+
10+## 0.1.1.0
11+
12+* Package is more organized and now has tests and benchmarks separated
13+* Repository is more organized and clean
14+* Added CI
15+
16+[1]: https://pvp.haskell.org
17+[2]: https://github.com/bolt12/laop2/releases
ChangeLog.mddeleted−3
@@ -1,3 +0,0 @@
1−# Changelog for laop
2−
3−## Unreleased changes
LICENSE+17−26
@@ -1,30 +1,21 @@
1−Copyright Armando Santos (c) 2019
1+MIT License
22
3−All rights reserved.
3+Copyright (c) 2020 Armando Santos
44
5−Redistribution and use in source and binary forms, with or without
6−modification, are permitted provided that the following conditions are met:
5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
711
8− * Redistributions of source code must retain the above copyright
9− notice, this list of conditions and the following disclaimer.
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
1014
11− * Redistributions in binary form must reproduce the above
12− copyright notice, this list of conditions and the following
13− disclaimer in the documentation and/or other materials provided
14− with the distribution.
15−
16− * Neither the name of Armando Santos nor the names of other
17− contributors may be used to endorse or promote products derived
18− from this software without specific prior written permission.
19−
20−THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21−"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22−LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23−A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24−OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25−SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26−LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27−DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28−THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29−(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30−OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
README.md+34−30
@@ -1,5 +1,11 @@
11# laop - Linear Algebra of Programming library
22
3+[![GitHub CI](https://github.com/bolt12/laop/workflows/CI/badge.svg)](https://github.com/bolt12/laop/actions)
4+[![Build status](https://img.shields.io/travis/bolt12/laop.svg?logo=travis)](https://travis-ci.org/bolt12/laop)
5+[![Hackage](https://img.shields.io/hackage/v/laop.svg?logo=haskell)](https://hackage.haskell.org/package/laop)
6+[![Stackage Lts](http://stackage.org/package/laop/badge/lts)](http://stackage.org/lts/package/laop)
7+[![Stackage Nightly](http://stackage.org/package/laop/badge/nightly)](http://stackage.org/nightly/package/laop)
8+
39The LAoP discipline generalises relations and functions treating them as
410Boolean matrices and in turn consider these as arrows.
511
@@ -10,40 +16,38 @@ motivation behind the library, the underlying theory, and implementation details
1016This module offers many of the combinators mentioned in the work of
1117[Macedo (2012)](https://repositorium.sdum.uminho.pt/handle/1822/22894) and [Oliveira (2012)](https://pdfs.semanticscholar.org/ccf5/27fa9179081223bffe8067edd81948644fc0.pdf).
1218
13−See the package in hackage [here](https://hackage.haskell.org/package/laop-0.1.0.5)
14−
15−There are a couple of repos with a WIP of benchmarks comparing [matrix composition](https://github.com/bolt12/laop-benchmarks) and a real use case of [data analytics](https://github.com/bolt12/laop-analytics).
19+See the package in hackage [here](https://hackage.haskell.org/package/laop-0.1.1.0)
1620
17−A Functional Pearl is also on its way, hopefully will be the reference document for this library.
21+A Functional Pearl has been written and can be regarded as the [reference document](https://github.com/bolt12/tymfgg-pearl) for this library.
1822
1923## Features
2024
21−This library offers:
22−
23−- An internal module representation that uses normal datatypes (`Void`, `()`, `Either`) for matrix dimensions and two
24− type families `FromNat` and `Count` to make it easier to work with these type of matrices.
25−- An interfacing module that uses generalised types for the dimensions and is just a newtype wrapper
26− around the internal matrix data type.
27−- An interfacing module that uses type level naturals for the dimensions and is just a newtype wrapper
28− around the internal matrix data type.
29−- An interfacing module that restricts the matrix contents to being only 0's or 1's (True
30− and False). This module is called 'Relation' and offers many of the combinators seen in
31− AoP and Relational Calculus/Algebra.
32−- A very simple Probabilistic Programming module and several functions and data types to
33− make it easier to deal with sample space.
34−
35−Given this, this new matrix formulation compared to other libraries one has much more advantages, such as:
36−
37−- Has an inductive definition enabling writing matrix manipulation functions in a much more elegant and calculational way;
38−- Statically typed dimensions;
39−- Polymorphic data type dimensions;
40−- Polymorphic matrix content;
41−- Awesome dimension type inference;
42−- Fast type natural conversion via `FromNat` type family;
43−- Matrix `Junc` and `Split`-ing in O(1);
44−- Matrix composition takes advantage of divide-and-conquer and fusion laws.
45−
46−Unfortunately, this approach does not solve the issue of type dimensions being in some way constrainted making it impossible to write Arrow instances, for example. Type inference isn't perfect, when it comes to infer the types of matrices which dimensions are computed using type level naturals multiplication, the compiler needs type annotations in order to succeed.
25+This library offers 3 main matrix programming modules:
26+
27+- One in which matrices are typed with type level natural numbers;
28+- One in which matrices are typed with arbitrary generic data types;
29+- One in which matrices are regarded as relations, i.e. boolean matrices;
30+
31+There's also an experimental module that uses matrices to represent probability
32+distributions.
33+
34+The most interesting feature is that matrices are represented as an inductive data type.
35+Given this formulation, matrix algorithms can be expressed in a much more elegant and
36+calculational style than the traditional vector of vectors representation. This data type
37+guarantees that a matrix will always have valid dimensions. It can also express block matrix
38+computations naturally, which leads to total, efficient and statically typed manipulation
39+and transformation functions.
40+
41+Like matrix multiplication, other common operations, such as matrix transposition, benefit from a block-oriented structure that leads to a simple and natural divide-and-conquer algorithmic solution. Performance wise, this means that without much effort we can obtain optimal cache-oblivious algorithms.
42+
43+Given this, this new matrix formulation compared to other libraries:
44+
45+- Is more compositional and polymorphic and does not have partial matrix manipulation functions (hence less chances for usage errors);
46+- Our implementation of matrices enables simple manipulation of submatrices, making it particularly suitable for formal verification and equation reasoning, using the mathematical framework defined by the linear algebra of programming. Furthermore, the data type constructors ensure that the matrices of this kind are sound, i.e. malformed matrices with incorrect dimensions of the sort, can not be constructed.
47+
48+## Known issues
49+
50+Unfortunately, due to the use of type-level programming features, this approach sometimes requires type dimensions to be constrainted, in some way, impossible to write idiomatic Arrow instances, for example. Type inference isn't perfect, when it comes to infer the types of matrices which dimensions are computed using type level naturals multiplication, the compiler needs type annotations in order to succeed. And not all kinds of programs can be modeled using matrices, namely programs that deal with arbitrary infinite data types such as lists or integers (although there are some workarounds).
4751
4852## Notes
4953
Setup.hsdeleted−2
@@ -1,2 +0,0 @@
1−import Distribution.Simple
2−main = defaultMain
app/Main.hsdeleted−7
@@ -1,7 +0,0 @@
1−module Main where
2−
3−import Examples
4−import Benchmarks
5−
6−main :: IO ()
7−main = benchmark
appveyor.ymlnew file+34
@@ -0,0 +1,34 @@
1+clone_folder: "c:\\WORK"
2+clone_depth: 5
3+
4+# Do not build feature branch with open Pull Requests
5+skip_branch_with_pr: true
6+
7+platform:
8+ - x86_64
9+
10+cache:
11+ - "C:\\SR"
12+ - dist-newstyle
13+
14+environment:
15+ global:
16+ CABOPTS: --store-dir=C:\\SR
17+
18+ matrix:
19+ - GHCVER: 8.6.5
20+
21+install:
22+ - choco source add -n mistuke -s https://www.myget.org/F/mistuke/api/v2
23+ - choco install -y cabal --version 2.4.1.0
24+ - choco install -y ghc --version 8.6.3
25+ - refreshenv
26+
27+before_build:
28+ - cabal --version
29+ - ghc --version
30+ - cabal %CABOPTS% v2-update
31+
32+build_script:
33+ - cabal %CABOPTS% v2-build --enable-tests
34+ - cabal %CABOPTS% v2-test --enable-tests
app/Benchmarks.hs → benchmark/Main.hsrenamed+11−13
@@ -8,30 +8,28 @@
88{-# LANGUAGE AllowAmbiguousTypes #-}
99{-# LANGUAGE ScopedTypeVariables #-}
1010
11−module Benchmarks
12− ( benchmark
13− )
14− where
11+module Main (main) where
1512
1613import LAoP.Dist.Internal
1714import LAoP.Utils
18−import LAoP.Matrix.Type hiding (CountableN, Countable, FromListsN)
19−import qualified LAoP.Matrix.Type as T (FromListsN)
15+import LAoP.Matrix.Type hiding (CountableN, Countable, FLN)
16+import qualified LAoP.Matrix.Type as T (FLN)
2017import Criterion.Main
2118import Control.DeepSeq
2219import Test.QuickCheck
2320import GHC.TypeLits
2421import Data.Proxy
22+import Prelude hiding (id, (.))
2523
2624selectM2 ::
2725 ( Num e,
28− T.FromListsN e b b,
26+ T.FLN b b,
2927 CountableN b
3028 ) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
3129selectM2 m y = join y iden `comp` m
3230
3331selectD2 ::
34− ( FromListsN b b,
32+ ( FLN b b,
3533 CountableN b
3634 ) => Dist (Either a b) -> Matrix Prob a b -> Dist b
3735selectD2 (D d) m = D (join m iden `comp` d)
@@ -39,7 +37,7 @@ selectD2 (D d) m = D (join m iden `comp` d)
3937-- Composition with iden
4038compId m = comp iden m
4139
42−randomDist :: forall a . (Countable a, FromListsN () a) => Gen (Dist a)
40+randomDist :: forall a . (Countable a, FLN () a) => Gen (Dist a)
4341randomDist = do
4442 let size = fromInteger (natVal (Proxy :: Proxy (Count a)))
4543 l <- vectorOf size (arbitrary :: Gen Prob)
@@ -48,7 +46,7 @@ randomDist = do
4846 m = fromLists lr
4947 return (D m)
5048
51−randomMatrix :: forall a b . (CountableDimensions a b, FromListsN a b) => Gen (Matrix Prob a b)
49+randomMatrix :: forall a b . (CountableDims a b, FLN a b) => Gen (Matrix Prob a b)
5250randomMatrix = do
5351 let cols = fromInteger (natVal (Proxy :: Proxy (Count a)))
5452 rows = fromInteger (natVal (Proxy :: Proxy (Count b)))
@@ -107,7 +105,7 @@ normalize3 as l = let s = sum l
107105 probs = map (/ s) l
108106 in zip as probs
109107
110−randomDistF :: forall a b . (CountableDimensions a b, CoArbitrary a, Arbitrary b) => Gen (Dist' (a -> b))
108+randomDistF :: forall a b . (CountableDims a b, CoArbitrary a, Arbitrary b) => Gen (Dist' (a -> b))
111109randomDistF = do
112110 let a = fromInteger (natVal (Proxy :: Proxy (Count a)))
113111 b = fromInteger (natVal (Proxy :: Proxy (Count b)))
@@ -146,8 +144,8 @@ setupEnv2 = do
146144 distList2 <- generate (resize 1 (randomDistF @(Natural 0 100) @(Natural 0 100)))
147145 return (m21, m40, dist, dist2, distList1, distList2)
148146
149−benchmark :: IO ()
150−benchmark = defaultMain [
147+main :: IO ()
148+main = defaultMain [
151149 env setupEnv $ \ ~(m11, m12, m21, m22, m31, m32) -> bgroup "Matrix Composition" [
152150 bgroup "10x10" [
153151 bench "WHNF - 10x10" $ whnf (comp m11) m12
hackage.shdeleted−10
@@ -1,10 +0,0 @@
1−#!/bin/sh
2−set -e
3−
4−dir=$(mktemp -d dist-docs.XXXXXX)
5−trap 'rm -r "$dir"' EXIT
6−
7−# assumes cabal 2.4 or later
8−cabal v2-haddock --builddir="$dir" --haddock-for-hackage --enable-doc
9−
10−cabal upload -d $dir/*-docs.tar.gz --publish
laop.cabalnew file+89
@@ -0,0 +1,89 @@
1+cabal-version: 2.4
2+name: laop
3+version: 0.1.1.1
4+synopsis: Matrix programming library
5+description: Matrix programming library that uses a type-safe inductive definition
6+ inspired by the Linear Algebra of Programming
7+homepage: https://github.com/bolt12/laop
8+bug-reports: https://github.com/bolt12/laop/issues
9+license: MIT
10+license-file: LICENSE
11+author: Armando Santos
12+maintainer: Armando Santos <armandoifsantos@gmail.com>
13+copyright: 2020 Armando Santos
14+category: Data
15+build-type: Simple
16+extra-doc-files: README.md
17+ CHANGELOG.md
18+tested-with: GHC == 8.6.5
19+ GHC == 8.8.3
20+
21+source-repository head
22+ type: git
23+ location: https://github.com/bolt12/laop.git
24+
25+common common-options
26+ build-depends: base >= 4.12.0.0 && < 5,
27+ deepseq
28+
29+ ghc-options: -Wall
30+ -Wcompat
31+ -Widentities
32+ -Wincomplete-uni-patterns
33+ -Wincomplete-record-updates
34+ if impl(ghc >= 8.0)
35+ ghc-options: -Wredundant-constraints
36+ if impl(ghc >= 8.2)
37+ ghc-options: -fhide-source-paths
38+ if impl(ghc >= 8.4)
39+ ghc-options: -Wmissing-export-lists
40+ -Wpartial-fields
41+ if impl(ghc >= 8.8)
42+ ghc-options: -Wmissing-deriving-strategies
43+
44+ default-language: Haskell2010
45+
46+library
47+ import: common-options
48+ hs-source-dirs: src
49+ exposed-modules: LAoP.Dist
50+ LAoP.Dist.Internal
51+ LAoP.Matrix.Internal
52+ LAoP.Matrix.Nat
53+ LAoP.Matrix.Type
54+ LAoP.Relation
55+ LAoP.Relation.Internal
56+ LAoP.Utils
57+ LAoP.Utils.Internal
58+
59+test-suite laop-test
60+ import: common-options
61+ type: exitcode-stdio-1.0
62+ hs-source-dirs: test
63+ other-modules: Examples.Readme
64+ main-is: Spec.hs
65+ build-depends: laop
66+ ghc-options: -threaded
67+ -rtsopts
68+ -with-rtsopts=-N
69+ -funfolding-use-threshold=16
70+ -fexcess-precision
71+ -optc-O3
72+ -optc-ffast-math
73+
74+benchmark laop-benchmark
75+ import: common-options
76+ type: exitcode-stdio-1.0
77+ hs-source-dirs: benchmark
78+ main-is: Main.hs
79+ build-depends: criterion
80+ , QuickCheck
81+ , deepseq
82+ , laop
83+ ghc-options: -threaded
84+ -rtsopts
85+ -with-rtsopts=-N
86+ -funfolding-use-threshold=16
87+ -fexcess-precision
88+ -optc-O3
89+ -optc-ffast-math
package.yamldeleted−57
@@ -1,57 +0,0 @@
1−name: laop
2−version: 0.1.0.5
3−github: "bolt12/laop"
4−license: BSD3
5−author: "Armando Santos"
6−maintainer: "armandoifsantos@gmail.com"
7−copyright: "MIT"
8−
9−extra-source-files:
10−- README.md
11−- ChangeLog.md
12−
13−# Metadata used when publishing your package
14−# synopsis: Short description of your package
15−category: Data
16−
17−# To avoid duplicated efforts in documentation and dealing with the
18−# complications of embedding Haddock markup inside cabal files, it is
19−# common to point users to the README.md file.
20−description: Please see the README on GitHub at <https://github.com/bolt12/laop#readme>
21−
22−dependencies:
23−- base >= 4.7 && < 5
24−- deepseq
25−
26−library:
27− source-dirs: src
28−
29−executables:
30− laop-exe:
31− main: Main.hs
32− source-dirs: app
33− ghc-options:
34− - -threaded
35− - -rtsopts
36− - -with-rtsopts=-N
37− - -funfolding-use-threshold=16
38− - -fexcess-precision # Good for doubles
39− - -optc-O3 # Good for doubles
40− - -optc-ffast-math # Good for doubles
41− - -O2
42− dependencies:
43− - laop
44− - criterion
45− - deepseq
46− - QuickCheck
47−
48−tests:
49− laop-test:
50− main: Spec.hs
51− source-dirs: test
52− ghc-options:
53− - -threaded
54− - -rtsopts
55− - -with-rtsopts=-N
56− dependencies:
57− - laop
src/LAoP/Dist.hs+2−2
@@ -39,8 +39,8 @@ module LAoP.Dist
3939 -- * Constraint type synonyms
4040 Countable,
4141 CountableN,
42− CountableDimensionsN,
43− FromListsN,
42+ CountableDimsN,
43+ FLN,
4444 Liftable,
4545 TrivialP,
4646
src/LAoP/Dist/Internal.hs+44−43
@@ -16,8 +16,8 @@ module LAoP.Dist.Internal
1616
1717 Countable,
1818 CountableN,
19− CountableDimensionsN,
20− FromListsN,
19+ CountableDimsN,
20+ FLN,
2121 Liftable,
2222 TrivialP,
2323
@@ -43,7 +43,8 @@ module LAoP.Dist.Internal
4343 )
4444 where
4545
46−import LAoP.Matrix.Type hiding (TrivialP, Countable, CountableDimensions, CountableN, CountableDimensionsN, Liftable, FromListsN)
46+import LAoP.Matrix.Type hiding (TrivialP, Countable, CountableDims, CountableN, CountableDimsN, Liftable, FLN)
47+import Prelude hiding (id, (.))
4748import qualified LAoP.Matrix.Internal as I
4849import LAoP.Utils
4950import GHC.TypeLits
@@ -61,18 +62,18 @@ newtype Dist a = D (Matrix Prob () a)
6162 deriving (Show, Num, Eq, Ord, NFData) via (Matrix Prob () a)
6263
6364-- | Constraint type synonyms to keep the type signatures less convoluted
64−type Countable a = KnownNat (I.Count a)
65−type CountableN a = KnownNat (I.Count (I.Normalize a))
66−type CountableDimensionsN a b = (CountableN a, CountableN b)
67−type FromListsN a b = I.FromLists Prob (I.Normalize a) (I.Normalize b)
68−type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num Prob, Ord Prob)
69−type TrivialP a b = Normalize (a, b) ~ Normalize (Normalize a, Normalize b)
65+type Countable a = KnownNat (I.Count a)
66+type CountableN a = KnownNat (I.Count (I.Normalize a))
67+type CountableDimsN a b = (CountableN a, CountableN b)
68+type FLN a b = I.FL (I.Normalize a) (I.Normalize b)
69+type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num Prob, Ord Prob)
70+type TrivialP a b = Normalize (a, b) ~ Normalize (Normalize a, Normalize b)
7071
7172-- | Functor instance
7273fmapD ::
7374 ( Liftable a b,
74− CountableDimensionsN a b,
75− FromListsN b a
75+ CountableDimsN a b,
76+ FLN b a
7677 )
7778 =>
7879 (a -> b) -> Dist a -> Dist b
@@ -84,17 +85,17 @@ unitD = D (one 1)
8485
8586-- | Applicative/Monoidal instance 'mult' function
8687multD ::
87− ( CountableDimensionsN a b,
88+ ( CountableDimsN a b,
8889 CountableN (a, b),
89− FromListsN (a, b) a,
90− FromListsN (a, b) b,
90+ FLN (a, b) a,
91+ FLN (a, b) b,
9192 TrivialP a b
9293 ) => Dist a -> Dist b -> Dist (a, b)
9394multD (D a) (D b) = D (kr a b)
9495
9596-- | Selective instance function
9697selectD ::
97− ( FromListsN b b,
98+ ( FLN b b,
9899 CountableN b
99100 ) => Dist (Either a b) -> Matrix Prob a b -> Dist b
100101selectD (D d) m = D (selectM d m)
@@ -103,17 +104,17 @@ selectD (D d) m = D (selectM d m)
103104-- functions to apply to a given argument;
104105branchD ::
105106 ( Num e,
106− CountableDimensionsN a b,
107− CountableDimensionsN c (Either b c),
108− FromListsN c b,
109− FromListsN a b,
110− FromListsN a a,
111− FromListsN b b,
112− FromListsN c c,
113− FromListsN b a,
114− FromListsN b c,
115− FromListsN (Either b c) b,
116− FromListsN (Either b c) c
107+ CountableDimsN a b,
108+ CountableDimsN c (Either b c),
109+ FLN c b,
110+ FLN a b,
111+ FLN a a,
112+ FLN b b,
113+ FLN c c,
114+ FLN b a,
115+ FLN b c,
116+ FLN (Either b c) b,
117+ FLN (Either b c) c
117118 )
118119 => Dist (Either a b) -> Matrix Prob a c -> Matrix Prob b c -> Dist c
119120branchD x l r = f x `selectD` g l `selectD` r
@@ -123,11 +124,11 @@ branchD x l r = f x `selectD` g l `selectD` r
123124
124125-- | Branch on a Boolean value, skipping unnecessary computations.
125126ifD ::
126− ( CountableDimensionsN a (Either () a),
127− FromListsN a a,
128− FromListsN a (),
129− FromListsN () a,
130− FromListsN (Either () a) a
127+ ( CountableDimsN a (Either () a),
128+ FLN a a,
129+ FLN a (),
130+ FLN () a,
131+ FLN (Either () a) a
131132 )
132133 => Dist Bool -> Dist a -> Dist a -> Dist a
133134ifD x (D t) (D e) = branchD x' t e
@@ -135,7 +136,7 @@ ifD x (D t) (D e) = branchD x' t e
135136 x' = bool (Right ()) (Left ()) `fmapD` x
136137
137138-- | Monad instance 'return' function
138−returnD :: forall a . (Enum a, FromListsN () a, Countable a) => a -> Dist a
139+returnD :: forall a . (Enum a, FLN () a, Countable a) => a -> Dist a
139140returnD a = D (col l)
140141 where
141142 i = fromInteger $ natVal (Proxy :: Proxy (Count a))
@@ -150,7 +151,7 @@ bindD (D d) m = D (m `comp` d)
150151(??) ::
151152 ( Enum a,
152153 Countable a,
153− FromListsN () a
154+ FLN () a
154155 ) => (a -> Bool) -> Dist a -> Prob
155156(??) p d =
156157 let l = toValues d
@@ -160,11 +161,11 @@ bindD (D d) m = D (m `comp` d)
160161-- Distribution Construction
161162
162163-- | Constructs a Bernoulli distribution
163−choose :: (FromListsN () a) => Prob -> Dist a
164+choose :: (FLN () a) => Prob -> Dist a
164165choose prob = D (col [prob, 1 - prob])
165166
166167-- | Creates a distribution given a shape function
167−shape :: (FromListsN () a) => (Prob -> Prob) -> [a] -> Dist a
168+shape :: (FLN () a) => (Prob -> Prob) -> [a] -> Dist a
168169shape _ [] = error "Probability.shape: empty list"
169170shape f xs =
170171 let incr = 1 / fromIntegral (length xs - 1)
@@ -172,23 +173,23 @@ shape f xs =
172173 in fromFreqs (zip xs ps)
173174
174175-- | Constructs a Linear distribution
175−linear :: (FromListsN () a) => [a] -> Dist a
176+linear :: (FLN () a) => [a] -> Dist a
176177linear = shape id
177178
178179-- | Constructs an Uniform distribution
179−uniform :: (FromListsN () a) => [a] -> Dist a
180+uniform :: (FLN () a) => [a] -> Dist a
180181uniform = shape (const 1)
181182
182183-- | Constructs an Negative Exponential distribution
183−negExp :: (FromListsN () a) => [a] -> Dist a
184+negExp :: (FLN () a) => [a] -> Dist a
184185negExp = shape (\x -> exp (-x))
185186
186187-- | Constructs an Normal distribution
187−normal :: (FromListsN () a) => [a] -> Dist a
188+normal :: (FLN () a) => [a] -> Dist a
188189normal = shape (normalCurve 0.5 0.5)
189190
190191-- | Transforms a 'Dist' into a list of pairs.
191−toValues :: forall a . (Enum a, Countable a, FromListsN () a) => Dist a -> [(a, Prob)]
192+toValues :: forall a . (Enum a, Countable a, FLN () a) => Dist a -> [(a, Prob)]
192193toValues (D d) =
193194 let rows = fromInteger (natVal (Proxy :: Proxy (Count a)))
194195 probs = toList d
@@ -196,7 +197,7 @@ toValues (D d) =
196197 in res
197198
198199-- | Pretty a distribution
199−prettyDist :: forall a. (Show a, Enum a, Countable a, FromListsN () a) => Dist a -> String
200+prettyDist :: forall a. (Show a, Enum a, Countable a, FLN () a) => Dist a -> String
200201prettyDist d =
201202 let values = sortBy (\(a, p1) (b, p2) -> compare p2 p1) (toValues @a d)
202203 w = maximum (map (length . show . fst) values)
@@ -208,12 +209,12 @@ prettyDist d =
208209 showR n x = show x ++ " "
209210
210211-- | Pretty Print a distribution
211−prettyPrintDist :: forall a . (Show a, Enum a, Countable a, FromListsN () a) => Dist a -> IO ()
212+prettyPrintDist :: forall a . (Show a, Enum a, Countable a, FLN () a) => Dist a -> IO ()
212213prettyPrintDist = putStrLn . prettyDist @a
213214
214215-- Auxiliary functions
215216
216−fromFreqs :: (FromListsN () a) => [(a,Prob)] -> Dist a
217+fromFreqs :: (FLN () a) => [(a,Prob)] -> Dist a
217218fromFreqs xs = D (col (map (\(x,p) -> p/q) xs))
218219 where q = sum $ map snd xs
219220
src/LAoP/Matrix/Internal.hs+174−211
@@ -30,7 +30,7 @@
3030-- motivation behind the library, the underlying theory, and implementation details.
3131--
3232-- This module offers many of the combinators mentioned in the work of
33−-- Macedo (2012) and Oliveira (2012).
33+-- Macedo (2012) and Oliveira (2012).
3434--
3535-- This is an Internal module and it is no supposed to be imported.
3636--
@@ -43,14 +43,23 @@ module LAoP.Matrix.Internal
4343 --
4444 -- There exists two type families that make it easier to write
4545 -- matrix dimensions: 'FromNat' and 'Count'. This approach
46− -- leads to a very straightforward implementation
47− -- of LAoP combinators.
46+ -- leads to a very straightforward implementation
47+ -- of LAoP combinators.
4848
4949 -- * Type safe matrix representation
5050 Matrix (..),
5151
52+ -- * Constraint type aliases
53+ Countable,
54+ CountableDims,
55+ CountableN,
56+ CountableDimsN,
57+ FL,
58+ FLN,
59+ Liftable,
60+ Trivial,
61+
5262 -- * Primitives
53− empty,
5463 one,
5564 join,
5665 fork,
@@ -66,6 +75,7 @@ module LAoP.Matrix.Internal
6675 toLists,
6776 toList,
6877 matrixBuilder,
78+ matrixBuilder',
6979 row,
7080 col,
7181 zeros,
@@ -76,7 +86,9 @@ module LAoP.Matrix.Internal
7686 -- * Misc
7787 -- ** Get dimensions
7888 columns,
89+ columns',
7990 rows,
91+ rows',
8092
8193 -- ** Matrix Transposition
8294 tr,
@@ -118,6 +130,7 @@ module LAoP.Matrix.Internal
118130
119131 -- | Note that given the restrictions imposed it is not possible to
120132 -- implement the standard type classes present in standard Haskell.
133+
121134 -- *** Matrix pairing projections
122135 fstM,
123136 sndM,
@@ -163,17 +176,17 @@ import Data.Kind
163176import Data.List
164177import Data.Maybe
165178import Data.Proxy
179+import Data.Typeable
166180import Data.Void
167181import GHC.TypeLits
168182import Data.Type.Equality
169183import GHC.Generics
170184import Control.DeepSeq
171−import Control.Category
172−import Prelude hiding ((.))
185+import Prelude hiding (id, (.))
186+import qualified Prelude (id, (.))
173187
174188-- | LAoP (Linear Algebra of Programming) Inductive Matrix definition.
175189data Matrix e cols rows where
176− Empty :: Matrix e Void Void
177190 One :: e -> Matrix e () ()
178191 Join :: Matrix e a rows -> Matrix e b rows -> Matrix e (Either a b) rows
179192 Fork :: Matrix e cols a -> Matrix e cols b -> Matrix e cols (Either a b)
@@ -203,7 +216,6 @@ type family Count (d :: Type) :: Nat where
203216--
204217-- Thanks to Li-Yao Xia this type family is super fast.
205218type family FromNat (n :: Nat) :: Type where
206− FromNat 0 = Void
207219 FromNat 1 = ()
208220 FromNat n = FromNat' (Mod n 2 == 0) (FromNat (Div n 2))
209221
@@ -220,29 +232,26 @@ type family Normalize (d :: Type) :: Type where
220232-- | Constraint type synonyms to keep the type signatures less convoluted
221233type Countable a = KnownNat (Count a)
222234type CountableN a = KnownNat (Count (Normalize a))
223−type CountableDimensions a b = (Countable a, Countable b)
224−type CountableDimensionsN a b = (CountableN a, CountableN b)
225−type FromListsN e a b = FromLists e (Normalize a) (Normalize b)
235+type CountableDims a b = (Countable a, Countable b)
236+type CountableDimsN a b = (CountableN a, CountableN b)
237+type FL a b = FromLists a b
238+type FLN a b = FromLists (Normalize a) (Normalize b)
226239type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
227240type Trivial a = FromNat (Count a) ~ a
228241
229−-- | It isn't possible to implement the 'id' function so it's
230−-- implementation is 'undefined'. However 'comp' can be and this partial
231−-- class implementation exists just to make the code more readable.
232−--
233−-- Please use 'iden' instead.
242+-- | It is possible to implement a constrained version of the category type
243+-- class.
234244instance (Num e) => Category (Matrix e) where
235− id = undefined
236− (.) = comp
245+ type Object (Matrix e) a = (FL a a, Countable a)
246+ id = iden
247+ (.) = comp
237248
238249instance NFData e => NFData (Matrix e cols rows) where
239− rnf Empty = ()
240250 rnf (One e) = rnf e
241251 rnf (Join a b) = rnf a `seq` rnf b
242252 rnf (Fork a b) = rnf a `seq` rnf b
243253
244254instance Eq e => Eq (Matrix e cols rows) where
245− Empty == Empty = True
246255 (One a) == (One b) = a == b
247256 (Join a b) == (Join c d) = a == c && b == d
248257 (Fork a b) == (Fork c d) = a == c && b == d
@@ -250,25 +259,21 @@ instance Eq e => Eq (Matrix e cols rows) where
250259 x@(Join _ _) == y@(Fork _ _) = abideJF x == y
251260
252261instance Num e => Num (Matrix e cols rows) where
253−
254262 a + b = zipWithM (+) a b
255263
256264 a - b = zipWithM (-) a b
257265
258266 a * b = zipWithM (*) a b
259267
260− abs Empty = Empty
261268 abs (One a) = One (abs a)
262269 abs (Join a b) = Join (abs a) (abs b)
263270 abs (Fork a b) = Fork (abs a) (abs b)
264271
265− signum Empty = Empty
266272 signum (One a) = One (signum a)
267273 signum (Join a b) = Join (signum a) (signum b)
268274 signum (Fork a b) = Fork (signum a) (signum b)
269275
270276instance Ord e => Ord (Matrix e cols rows) where
271− Empty <= Empty = True
272277 (One a) <= (One b) = a <= b
273278 (Join a b) <= (Join c d) = (a <= c) && (b <= d)
274279 (Fork a b) <= (Fork c d) = (a <= c) && (b <= d)
@@ -277,10 +282,6 @@ instance Ord e => Ord (Matrix e cols rows) where
277282
278283-- Primitives
279284
280−-- | Empty matrix constructor
281−empty :: Matrix e Void Void
282−empty = Empty
283−
284285-- | Unit matrix constructor
285286one :: e -> Matrix e () ()
286287one = One
@@ -311,40 +312,39 @@ infixl 2 ===
311312--
312313-- Given that it is not possible to branch on types at the term level type
313314-- classes are needed very much like an inductive definition but on types.
314−class FromLists e cols rows where
315+class FromLists cols rows where
315316 -- | Build a matrix out of a list of list of elements. Throws a runtime
316317 -- error if the dimensions do not match.
317318 fromLists :: [[e]] -> Matrix e cols rows
318319
319−instance FromLists e Void Void where
320− fromLists [] = Empty
321− fromLists _ = error "Wrong dimensions"
322−
323−instance {-# OVERLAPPING #-} FromLists e () () where
320+instance FromLists () () where
324321 fromLists [[e]] = One e
325322 fromLists _ = error "Wrong dimensions"
326323
327−instance {-# OVERLAPPING #-} (FromLists e cols ()) => FromLists e (Either () cols) () where
324+instance (FromLists cols ()) => FromLists (Either () cols) () where
328325 fromLists [h : t] = Join (One h) (fromLists [t])
329326 fromLists _ = error "Wrong dimensions"
330327
331−instance {-# OVERLAPPABLE #-} (FromLists e a (), FromLists e b (), Countable a) => FromLists e (Either a b) () where
328+instance {-# OVERLAPPABLE #-}
329+ (FromLists a (), FromLists b (), Countable a) => FromLists (Either a b) () where
332330 fromLists [l] =
333331 let rowsA = fromInteger (natVal (Proxy :: Proxy (Count a)))
334332 in Join (fromLists [take rowsA l]) (fromLists [drop rowsA l])
335333 fromLists _ = error "Wrong dimensions"
336334
337−instance {-# OVERLAPPING #-} (FromLists e () rows) => FromLists e () (Either () rows) where
335+instance (FromLists () rows) => FromLists () (Either () rows) where
338336 fromLists ([h] : t) = Fork (One h) (fromLists t)
339337 fromLists _ = error "Wrong dimensions"
340338
341−instance {-# OVERLAPPABLE #-} (FromLists e () a, FromLists e () b, Countable a) => FromLists e () (Either a b) where
342− fromLists l@([_] : _) =
339+instance {-# OVERLAPPABLE #-}
340+ (FromLists () a, FromLists () b, Countable a) => FromLists () (Either a b) where
341+ fromLists l@([_] : _) =
343342 let rowsA = fromInteger (natVal (Proxy :: Proxy (Count a)))
344343 in Fork (fromLists (take rowsA l)) (fromLists (drop rowsA l))
345344 fromLists _ = error "Wrong dimensions"
346345
347−instance {-# OVERLAPPABLE #-} (FromLists e (Either a b) c, FromLists e (Either a b) d, Countable c) => FromLists e (Either a b) (Either c d) where
346+instance (FromLists (Either a b) c, FromLists (Either a b) d, Countable c)
347+ => FromLists (Either a b) (Either c d) where
348348 fromLists l@(h : t) =
349349 let lh = length h
350350 rowsC = fromInteger (natVal (Proxy :: Proxy (Count c)))
@@ -354,24 +354,44 @@ instance {-# OVERLAPPABLE #-} (FromLists e (Either a b) c, FromLists e (Either a
354354 else error "Not all rows have the same length"
355355
356356-- | Matrix builder function. Constructs a matrix provided with
357−-- a construction function.
358−matrixBuilder ::
357+-- a construction function that operates with indices.
358+matrixBuilder' ::
359359 forall e cols rows.
360− ( FromLists e cols rows,
361− CountableDimensions cols rows
360+ ( FL cols rows,
361+ CountableDims cols rows
362362 ) => ((Int, Int) -> e) -> Matrix e cols rows
363−matrixBuilder f =
363+matrixBuilder' f =
364364 let c = fromInteger $ natVal (Proxy :: Proxy (Count cols))
365365 r = fromInteger $ natVal (Proxy :: Proxy (Count rows))
366366 positions = [(a, b) | a <- [0 .. (r - 1)], b <- [0 .. (c - 1)]]
367367 in fromLists . map (map f) . groupBy (\(x, _) (w, _) -> x == w) $ positions
368368
369+-- | Matrix builder function. Constructs a matrix provided with
370+-- a construction function that operates with arbitrary types.
371+matrixBuilder ::
372+ forall e a b.
373+ ( FLN a b,
374+ Enum a,
375+ Enum b,
376+ Bounded a,
377+ Bounded b,
378+ Eq a,
379+ Countable b
380+ ) => ((a, b) -> e) -> Matrix e (Normalize a) (Normalize b)
381+matrixBuilder f =
382+ let r = fromInteger $ natVal (Proxy :: Proxy (Count b))
383+ positions = [(a, b) | a <- [minBound .. maxBound], b <- [minBound .. maxBound]]
384+ in fromLists . map (map f) . transpose . buildList r $ positions
385+ where
386+ buildList _ [] = []
387+ buildList r l = take r l : buildList r (drop r l)
388+
369389-- | Constructs a column vector matrix
370−col :: (FromLists e () rows) => [e] -> Matrix e () rows
390+col :: (FL () rows) => [e] -> Matrix e () rows
371391col = fromLists . map (: [])
372392
373393-- | Constructs a row vector matrix
374−row :: (FromLists e cols ()) => [e] -> Matrix e cols ()
394+row :: (FL cols ()) => [e] -> Matrix e cols ()
375395row = fromLists . (: [])
376396
377397-- | Lifts functions to matrices with arbitrary dimensions.
@@ -381,8 +401,8 @@ row = fromLists . (: [])
381401fromF' ::
382402 forall a b cols rows e.
383403 ( Liftable e a b,
384− CountableDimensions cols rows,
385− FromLists e rows cols
404+ CountableDims cols rows,
405+ FL rows cols
386406 ) =>
387407 (a -> b) ->
388408 Matrix e cols rows
@@ -410,35 +430,17 @@ fromF' f =
410430fromF ::
411431 forall a b e.
412432 ( Liftable e a b,
413− CountableDimensionsN a b,
414− FromListsN e b a
433+ CountableDimsN a b,
434+ FLN b a
415435 ) =>
416436 (a -> b) ->
417437 Matrix e (Normalize a) (Normalize b)
418−fromF f =
419− let minA = minBound @a
420− maxA = maxBound @a
421− minB = minBound @b
422− maxB = maxBound @b
423− ccols = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize a)))
424− rrows = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize b)))
425− elementsA = take ccols [minA .. maxA]
426− elementsB = take rrows [minB .. maxB]
427− combinations = (,) <$> elementsA <*> elementsB
428− combAp = map snd . sort . map (\(a, b) -> if f a == b
429− then ((fromEnum a, fromEnum b), 1)
430− else ((fromEnum a, fromEnum b), 0)) $ combinations
431− mList = buildList combAp rrows
432− in tr $ fromLists mList
433− where
434− buildList [] _ = []
435− buildList l r = take r l : buildList (drop r l) r
438+fromF = fromF'
436439
437440-- Conversion
438441
439442-- | Converts a matrix to a list of lists of elements.
440443toLists :: Matrix e cols rows -> [[e]]
441−toLists Empty = []
442444toLists (One e) = [[e]]
443445toLists (Fork l r) = toLists l ++ toLists r
444446toLists (Join l r) = zipWith (++) (toLists l) (toLists r)
@@ -450,28 +452,28 @@ toList = concat . toLists
450452-- Zeros Matrix
451453
452454-- | The zero matrix. A matrix wholly filled with zeros.
453−zeros :: (Num e, FromLists e cols rows, CountableDimensions cols rows) => Matrix e cols rows
454−zeros = matrixBuilder (const 0)
455+zeros :: (Num e, FL cols rows, CountableDims cols rows) => Matrix e cols rows
456+zeros = matrixBuilder' (const 0)
455457
456458-- Ones Matrix
457459
458460-- | The ones matrix. A matrix wholly filled with ones.
459461--
460462-- Also known as T (Top) matrix.
461−ones :: (Num e, FromLists e cols rows, CountableDimensions cols rows) => Matrix e cols rows
462−ones = matrixBuilder (const 1)
463+ones :: (Num e, FL cols rows, CountableDims cols rows) => Matrix e cols rows
464+ones = matrixBuilder' (const 1)
463465
464466-- Const Matrix
465467
466468-- | The constant matrix constructor. A matrix wholly filled with a given
467469-- value.
468−constant :: (Num e, FromLists e cols rows, CountableDimensions cols rows) => e -> Matrix e cols rows
469−constant e = matrixBuilder (const e)
470+constant :: (Num e, FL cols rows, CountableDims cols rows) => e -> Matrix e cols rows
471+constant e = matrixBuilder' (const e)
470472
471473-- Bang Matrix
472474
473475-- | The T (Top) row vector matrix.
474−bang :: forall e cols. (Num e, Enum e, FromLists e cols (), Countable cols) => Matrix e cols ()
476+bang :: forall e cols. (Num e, Enum e, FL cols (), Countable cols) => Matrix e cols ()
475477bang =
476478 let c = fromInteger $ natVal (Proxy :: Proxy (Count cols))
477479 in fromLists [take c [1, 1 ..]]
@@ -479,8 +481,8 @@ bang =
479481-- iden Matrix
480482
481483-- | iden matrix.
482−iden :: (Num e, FromLists e cols cols, Countable cols) => Matrix e cols cols
483−iden = matrixBuilder (bool 0 1 . uncurry (==))
484+iden :: forall e cols . (Num e, FL cols cols, Countable cols) => Matrix e cols cols
485+iden = matrixBuilder' (bool 0 1 . uncurry (==))
484486{-# NOINLINE iden #-}
485487
486488-- Matrix composition (MMM)
@@ -490,13 +492,12 @@ iden = matrixBuilder (bool 0 1 . uncurry (==))
490492-- This definition takes advantage of divide-and-conquer and fusion laws
491493-- from LAoP.
492494comp :: (Num e) => Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
493−comp Empty Empty = Empty
494495comp (One a) (One b) = One (a * b)
495496comp (Join a b) (Fork c d) = comp a c + comp b d -- Divide-and-conquer law
496497comp (Fork a b) c = Fork (comp a c) (comp b c) -- Fork fusion law
497498comp c (Join a b) = Join (comp c a) (comp c b) -- Join fusion law
498499{-# NOINLINE comp #-}
499−{-# RULES
500+{-# RULES
500501 "comp/iden1" forall m. comp m iden = m ;
501502 "comp/iden2" forall m. comp iden m = m
502503#-}
@@ -506,7 +507,6 @@ comp c (Join a b) = Join (comp c a) (comp c b) -- Join fusion law
506507infixl 7 .|
507508-- | Scalar multiplication of matrices.
508509(.|) :: Num e => e -> Matrix e cols rows -> Matrix e cols rows
509−(.|) _ Empty = Empty
510510(.|) e (One a) = One (e * a)
511511(.|) e (Join a b) = Join (e .| a) (e .| b)
512512(.|) e (Fork a b) = Fork (e .| a) (e .| b)
@@ -516,7 +516,6 @@ infixl 7 .|
516516infixl 7 ./
517517-- | Scalar multiplication of matrices.
518518(./) :: Fractional e => Matrix e cols rows -> e -> Matrix e cols rows
519−(./) Empty _ = Empty
520519(./) (One a) e = One (a / e)
521520(./) (Join a b) e = Join (a ./ e) (b ./ e)
522521(./) (Fork a b) e = Fork (a ./ e) (b ./ e)
@@ -524,51 +523,59 @@ infixl 7 ./
524523-- Projections
525524
526525-- | Biproduct first component projection
527−p1 :: forall e m n. (Num e, CountableDimensions n m, FromLists e n m, FromLists e m m) => Matrix e (Either m n) m
528−p1 =
529− let iden = iden :: Matrix e m m
530− zero = zeros :: Matrix e n m
531− in join iden zero
526+p1 :: (Num e, CountableDims n m, FL n m, FL m m) => Matrix e (Either m n) m
527+p1 = join id zeros
532528
533529-- | Biproduct second component projection
534−p2 :: forall e m n. (Num e, CountableDimensions n m, FromLists e m n, FromLists e n n) => Matrix e (Either m n) n
535−p2 =
536− let iden = iden :: Matrix e n n
537− zero = zeros :: Matrix e m n
538− in join zero iden
530+p2 :: (Num e, CountableDims n m, FL m n, FL n n) => Matrix e (Either m n) n
531+p2 = join zeros id
539532
540533-- Injections
541534
542535-- | Biproduct first component injection
543−i1 :: (Num e, CountableDimensions n m, FromLists e n m, FromLists e m m) => Matrix e m (Either m n)
536+i1 :: (Num e, CountableDims n m, FL n m, FL m m) => Matrix e m (Either m n)
544537i1 = tr p1
545538
546539-- | Biproduct second component injection
547−i2 :: (Num e, CountableDimensions n m, FromLists e m n, FromLists e n n) => Matrix e n (Either m n)
540+i2 :: (Num e, CountableDims n m, FL m n, FL n n) => Matrix e n (Either m n)
548541i2 = tr p2
549542
550543-- Dimensions
551544
552545-- | Obtain the number of rows.
553546--
554−-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
555−-- dimensions in constant time.
556−--
557−-- TODO: A 'rows' function that does not need the 'KnownNat' constraint in
558−-- exchange for performance.
547+-- NOTE: The 'KnownNat' constraint is needed in order to obtain the
548+-- dimensions in constant time. For a version that doesn't require the
549+-- constraint see 'rows''.
559550rows :: forall e cols rows. (Countable rows) => Matrix e cols rows -> Int
560551rows _ = fromInteger $ natVal (Proxy :: Proxy (Count rows))
561552
553+-- | Obtain the number of rows in an inefficient manner, but without any
554+-- constraints.
555+--
556+-- For a more efficient version see 'rows'.
557+rows' :: Matrix e cols rows -> Int
558+rows' (One _) = 1
559+rows' (Join lhs _) = rows' lhs
560+rows' (Fork top bottom) = rows' top + rows' bottom
561+
562562-- | Obtain the number of columns.
563−--
564−-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
565−-- dimensions in constant time.
566563--
567−-- TODO: A 'columns' function that does not need the 'KnownNat' constraint in
568−-- exchange for performance.
564+-- NOTE: The 'KnownNat' constraint is needed in order to obtain the
565+-- dimensions in constant time. For a version that doesn't require the
566+-- constraint see 'columns''.
569567columns :: forall e cols rows. (Countable cols) => Matrix e cols rows -> Int
570568columns _ = fromInteger $ natVal (Proxy :: Proxy (Count cols))
571569
570+-- | Obtain the number of columns in an inefficient manner, but without any
571+-- constraints.
572+--
573+-- For a more efficient version see 'columns'.
574+columns' :: Matrix e cols rows -> Int
575+columns' (One _) = 1
576+columns' (Join lhs rhs) = columns' lhs + columns' rhs
577+columns' (Fork top _) = columns' top
578+
572579-- Coproduct Bifunctor
573580
574581infixl 5 -|-
@@ -577,11 +584,11 @@ infixl 5 -|-
577584(-|-) ::
578585 forall e n k m j.
579586 ( Num e,
580− CountableDimensions j k,
581− FromLists e k k,
582− FromLists e j k,
583− FromLists e k j,
584− FromLists e j j
587+ CountableDims j k,
588+ FL k k,
589+ FL j k,
590+ FL k j,
591+ FL j j
585592 ) =>
586593 Matrix e n k ->
587594 Matrix e m j ->
@@ -594,11 +601,11 @@ infixl 5 -|-
594601fstM ::
595602 forall e m k .
596603 ( Num e,
597− CountableDimensions k m,
598− FromLists e (Normalize (m, k)) m,
604+ CountableDims k m,
605+ FL (Normalize (m, k)) m,
599606 CountableN (m, k)
600607 ) => Matrix e (Normalize (m, k)) m
601−fstM = matrixBuilder f
608+fstM = matrixBuilder' f
602609 where
603610 offset = fromInteger (natVal (Proxy :: Proxy (Count k)))
604611 f (x, y)
@@ -609,11 +616,11 @@ fstM = matrixBuilder f
609616sndM ::
610617 forall e m k .
611618 ( Num e,
612− CountableDimensions k m,
613− FromLists e (Normalize (m, k)) k,
619+ CountableDims k m,
620+ FL (Normalize (m, k)) k,
614621 CountableN (m, k)
615622 ) => Matrix e (Normalize (m, k)) k
616−sndM = matrixBuilder f
623+sndM = matrixBuilder' f
617624 where
618625 offset = fromInteger (natVal (Proxy :: Proxy (Count k)))
619626 f (x, y)
@@ -623,7 +630,7 @@ sndM = matrixBuilder f
623630-- | Khatri Rao Matrix product also known as matrix pairing.
624631--
625632-- NOTE: That this is not a true categorical product, see for instance:
626−--
633+--
627634-- @
628635-- | fstM . kr a b == a
629636-- kr a b ==> |
@@ -634,15 +641,15 @@ sndM = matrixBuilder f
634641kr ::
635642 forall e cols a b.
636643 ( Num e,
637− CountableDimensions a b,
644+ CountableDims a b,
638645 CountableN (a, b),
639− FromLists e (Normalize (a, b)) a,
640− FromLists e (Normalize (a, b)) b
646+ FL (Normalize (a, b)) a,
647+ FL (Normalize (a, b)) b
641648 ) => Matrix e cols a -> Matrix e cols b -> Matrix e cols (Normalize (a, b))
642649kr a b =
643650 let fstM' = fstM @e @a @b
644651 sndM' = sndM @e @a @b
645− in tr fstM' . a * tr sndM' . b
652+ in (tr fstM' . a) * (tr sndM' . b)
646653
647654-- Product Bifunctor (Kronecker)
648655
@@ -652,14 +659,14 @@ infixl 4 ><
652659(><) ::
653660 forall e m p n q.
654661 ( Num e,
655− CountableDimensions m n,
656− CountableDimensions p q,
657− CountableDimensionsN (m, n) (p, q),
658− FromLists e (Normalize (m, n)) m,
659− FromLists e (Normalize (m, n)) n,
660− FromLists e (Normalize (p, q)) p,
661− FromLists e (Normalize (p, q)) q
662− )
662+ CountableDims m n,
663+ CountableDims p q,
664+ CountableDimsN (m, n) (p, q),
665+ FL (Normalize (m, n)) m,
666+ FL (Normalize (m, n)) n,
667+ FL (Normalize (p, q)) p,
668+ FL (Normalize (p, q)) q
669+ )
663670 => Matrix e m p -> Matrix e n q -> Matrix e (Normalize (m, n)) (Normalize (p, q))
664671(><) a b =
665672 let fstM' = fstM @e @m @n
@@ -677,7 +684,6 @@ infixl 4 ><
677684-- @
678685abideJF :: Matrix e cols rows -> Matrix e cols rows
679686abideJF (Join (Fork a c) (Fork b d)) = Fork (Join (abideJF a) (abideJF b)) (Join (abideJF c) (abideJF d)) -- Join-Fork abide law
680−abideJF Empty = Empty
681687abideJF (One e) = One e
682688abideJF (Join a b) = Join (abideJF a) (abideJF b)
683689abideJF (Fork a b) = Fork (abideJF a) (abideJF b)
@@ -691,7 +697,6 @@ abideJF (Fork a b) = Fork (abideJF a) (abideJF b)
691697-- @
692698abideFJ :: Matrix e cols rows -> Matrix e cols rows
693699abideFJ (Fork (Join a b) (Join c d)) = Join (Fork (abideFJ a) (abideFJ c)) (Fork (abideFJ b) (abideFJ d)) -- Fork-Join abide law
694−abideFJ Empty = Empty
695700abideFJ (One e) = One e
696701abideFJ (Join a b) = Join (abideFJ a) (abideFJ b)
697702abideFJ (Fork a b) = Fork (abideFJ a) (abideFJ b)
@@ -700,7 +705,6 @@ abideFJ (Fork a b) = Fork (abideFJ a) (abideFJ b)
700705
701706-- | Matrix transposition.
702707tr :: Matrix e cols rows -> Matrix e rows cols
703−tr Empty = Empty
704708tr (One e) = One e
705709tr (Join a b) = Fork (tr a) (tr b)
706710tr (Fork a b) = Join (tr a) (tr b)
@@ -709,32 +713,32 @@ tr (Fork a b) = Join (tr a) (tr b)
709713
710714-- | Selective functors 'select' operator equivalent inspired by the
711715-- ArrowMonad solution presented in the paper.
712−select :: (Num e, FromLists e b b, Countable b) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
716+select :: (Num e, FL b b, Countable b) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
713717select (Fork a b) y = y . a + b -- Divide-and-conquer law
714718select (Join (Fork a c) (Fork b d)) y = join (y . a + c) (y . b + d) -- Pattern matching + DnC law
715−select m y = join y iden . m
719+select m y = join y id . m
716720
717721branch ::
718722 ( Num e,
719− CountableDimensions a b,
720− CountableDimensions c (Either b c),
721− FromLists e c b,
722− FromLists e a b,
723− FromLists e a a,
724− FromLists e b b,
725− FromLists e c c,
726− FromLists e b a,
727− FromLists e b c,
728− FromLists e (Either b c) b,
729− FromLists e (Either b c) c
723+ CountableDims a b,
724+ CountableDims c (Either b c),
725+ FL c b,
726+ FL a b,
727+ FL a a,
728+ FL b b,
729+ FL c c,
730+ FL b a,
731+ FL b c,
732+ FL (Either b c) b,
733+ FL (Either b c) c
730734 )
731735 => Matrix e cols (Either a b) -> Matrix e a c -> Matrix e b c -> Matrix e cols c
732736branch x l r = f x `select` g l `select` r
733737 where
734− f :: (Num e, Countable a, CountableDimensions b c, FromLists e a b, FromLists e c b, FromLists e b b, FromLists e b a, FromLists e a a)
738+ f :: (Num e, Countable a, CountableDims b c, FL a b, FL c b, FL b b, FL b a, FL a a)
735739 => Matrix e cols (Either a b) -> Matrix e cols (Either a (Either b c))
736740 f m = fork (tr i1) (i1 . tr i2) . m
737− g :: (Num e, CountableDimensions b c, FromLists e b c, FromLists e c c) => Matrix e a c -> Matrix e a (Either b c)
741+ g :: (Num e, CountableDims b c, FL b c, FL c c) => Matrix e a c -> Matrix e a (Either b c)
738742 g m = i2 . m
739743
740744-- McCarthy's Conditional
@@ -743,9 +747,9 @@ branch x l r = f x `select` g l `select` r
743747cond ::
744748 ( Trivial cols,
745749 Countable cols,
746− FromLists e () cols,
747− FromLists e cols (),
748− FromLists e cols cols,
750+ FL () cols,
751+ FL cols (),
752+ FL cols cols,
749753 Bounded a,
750754 Enum a,
751755 Num e,
@@ -758,9 +762,9 @@ cond p f g = join f g . grd p
758762grd ::
759763 ( Trivial q,
760764 Countable q,
761− FromLists e () q,
762− FromLists e q (),
763− FromLists e q q,
765+ FL () q,
766+ FL q (),
767+ FL q q,
764768 Bounded a,
765769 Enum a,
766770 Num e,
@@ -774,14 +778,14 @@ corr ::
774778 forall e a q .
775779 ( Trivial q,
776780 Countable q,
777− FromLists e () q,
778− FromLists e q (),
779− FromLists e q q,
781+ FL () q,
782+ FL q (),
783+ FL q q,
780784 Liftable e a Bool
781785 )
782786 => (a -> Bool) -> Matrix e q q
783787corr p = let f = fromF' p :: Matrix e q ()
784− in kr f (iden :: Matrix e q q)
788+ in kr f (id :: Matrix e q q)
785789
786790-- Pretty print
787791
@@ -805,7 +809,7 @@ prettyAux (h : t) l = "│ " ++ fill (unwords $ map show h) ++ " │\n" ++
805809 fill str = replicate (widest - length str - 2) ' ' ++ str
806810
807811-- | Matrix pretty printer
808−pretty :: (CountableDimensions cols rows, Show e) => Matrix e cols rows -> String
812+pretty :: (CountableDims cols rows, Show e) => Matrix e cols rows -> String
809813pretty m = concat
810814 [ "┌ ", unwords (replicate (columns m) blank), " ┐\n"
811815 , unlines
@@ -834,12 +838,11 @@ pretty m = concat
834838 (safeGet i j m)
835839
836840-- | Matrix pretty printer
837−prettyPrint :: (CountableDimensions cols rows, Show e) => Matrix e cols rows -> IO ()
841+prettyPrint :: (CountableDims cols rows, Show e) => Matrix e cols rows -> IO ()
838842prettyPrint = putStrLn . pretty
839843
840844-- | Zip two matrices with a given binary function
841845zipWithM :: (e -> f -> g) -> Matrix e cols rows -> Matrix f cols rows -> Matrix g cols rows
842−zipWithM _ Empty Empty = Empty
843846zipWithM f (One a) (One b) = One (f a b)
844847zipWithM f (Join a b) (Join c d) = Join (zipWithM f a c) (zipWithM f b d)
845848zipWithM f (Fork a b) (Fork c d) = Fork (zipWithM f a c) (zipWithM f b d)
@@ -864,14 +867,12 @@ fromBool False = nat 0
864867
865868-- | Relational negation
866869negateM :: Relation cols rows -> Relation cols rows
867−negateM Empty = Empty
868870negateM (One (Nat p)) = One (Nat (negate p))
869871negateM (Join a b) = Join (negateM a) (negateM b)
870872negateM (Fork a b) = Fork (negateM a) (negateM b)
871873
872874-- | Relational addition
873875orM :: Relation cols rows -> Relation cols rows -> Relation cols rows
874−orM Empty Empty = Empty
875876orM (One a) (One b) = One (fromBool (toBool a || toBool b))
876877orM (Join a b) (Join c d) = Join (orM a c) (orM b d)
877878orM (Fork a b) (Fork c d) = Fork (orM a c) (orM b d)
@@ -880,7 +881,6 @@ orM x@(Join _ _) y@(Fork _ _) = orM (abideJF x) y
880881
881882-- | Relational multiplication
882883andM :: Relation cols rows -> Relation cols rows -> Relation cols rows
883−andM Empty Empty = Empty
884884andM (One a) (One b) = One (fromBool (toBool a && toBool b))
885885andM (Join a b) (Join c d) = Join (andM a c) (andM b d)
886886andM (Fork a b) (Fork c d) = Fork (andM a c) (andM b d)
@@ -889,7 +889,6 @@ andM x@(Join _ _) y@(Fork _ _) = andM (abideJF x) y
889889
890890-- | Relational subtraction
891891subM :: Relation cols rows -> Relation cols rows -> Relation cols rows
892−subM Empty Empty = Empty
893892subM (One a) (One b) = if a - b < nat 0 then One (nat 0) else One (a - b)
894893subM (Join a b) (Join c d) = Join (subM a c) (subM b d)
895894subM (Fork a b) (Fork c d) = Fork (subM a c) (subM b d)
@@ -898,7 +897,6 @@ subM x@(Join _ _) y@(Fork _ _) = subM (abideJF x) y
898897
899898-- | Matrix relational composition.
900899compRel :: Relation cr rows -> Relation cols cr -> Relation cols rows
901−compRel Empty Empty = Empty
902900compRel (One a) (One b) = One (fromBool (toBool a && toBool b))
903901compRel (Join a b) (Fork c d) = orM (compRel a c) (compRel b d) -- Divide-and-conquer law
904902compRel (Fork a b) c = Fork (compRel a c) (compRel b c) -- Fork fusion law
@@ -906,7 +904,6 @@ compRel c (Join a b) = Join (compRel c a) (compRel c b) -- Join fusion
906904
907905-- | Matrix relational right division
908906divR :: Relation b c -> Relation b a -> Relation a c
909−divR Empty Empty = Empty
910907divR (One a) (One b) = One (fromBool (not (toBool b) || toBool a)) -- b implies a
911908divR (Join a b) (Join c d) = andM (divR a c) (divR b d)
912909divR (Fork a b) c = Fork (divR a c) (divR b c)
@@ -929,58 +926,24 @@ divS s r = divL r s `intersection` divR (tr r) (tr s)
929926fromFRel' ::
930927 forall a b cols rows.
931928 ( Liftable Boolean a b,
932− CountableDimensions cols rows,
933− FromLists Boolean rows cols
929+ CountableDims cols rows,
930+ FL rows cols
934931 ) =>
935932 (a -> b) ->
936933 Relation cols rows
937−fromFRel' f =
938− let minA = minBound @a
939− maxA = maxBound @a
940− minB = minBound @b
941− maxB = maxBound @b
942− ccols = fromInteger $ natVal (Proxy :: Proxy (Count cols))
943− rrows = fromInteger $ natVal (Proxy :: Proxy (Count rows))
944− elementsA = take ccols [minA .. maxA]
945− elementsB = take rrows [minB .. maxB]
946− combinations = (,) <$> elementsA <*> elementsB
947− combAp = map snd . sort . map (\(a, b) -> if f a == b
948− then ((fromEnum a, fromEnum b), nat 1)
949− else ((fromEnum a, fromEnum b), nat 0)) $ combinations
950− mList = buildList combAp rrows
951− in tr $ fromLists mList
952− where
953− buildList [] _ = []
954− buildList l r = take r l : buildList (drop r l) r
934+fromFRel' = fromF'
955935
956936-- | Lifts functions to relations with dimensions matching @a@ and @b@
957937-- cardinality's.
958938fromFRel ::
959939 forall a b.
960940 ( Liftable Boolean a b,
961− CountableDimensionsN a b,
962− FromLists Boolean (Normalize b) (Normalize a)
941+ CountableDimsN a b,
942+ FLN b a
963943 ) =>
964944 (a -> b) ->
965945 Relation (Normalize a) (Normalize b)
966−fromFRel f =
967− let minA = minBound @a
968− maxA = maxBound @a
969− minB = minBound @b
970− maxB = maxBound @b
971− ccols = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize a)))
972− rrows = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize b)))
973− elementsA = take ccols [minA .. maxA]
974− elementsB = take rrows [minB .. maxB]
975− combinations = (,) <$> elementsA <*> elementsB
976− combAp = map snd . sort . map (\(a, b) -> if f a == b
977− then ((fromEnum a, fromEnum b), nat 1)
978− else ((fromEnum a, fromEnum b), nat 0)) $ combinations
979− mList = buildList combAp rrows
980− in tr $ fromLists mList
981− where
982− buildList [] _ = []
983− buildList l r = take r l : buildList (drop r l) r
946+fromFRel = fromFRel'
984947
985948-- | Lifts a relation function to a Boolean Matrix
986949toRel ::
@@ -990,17 +953,17 @@ toRel ::
990953 Enum a,
991954 Enum b,
992955 Eq b,
993− CountableDimensionsN a b,
994− FromListsN Boolean b a
995− )
956+ CountableDims a b,
957+ FLN b a
958+ )
996959 => (a -> b -> Bool) -> Relation (Normalize a) (Normalize b)
997960toRel f =
998961 let minA = minBound @a
999962 maxA = maxBound @a
1000963 minB = minBound @b
1001964 maxB = maxBound @b
1002− ccols = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize a)))
1003− rrows = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize b)))
965+ ccols = fromInteger $ natVal (Proxy :: Proxy (Count a))
966+ rrows = fromInteger $ natVal (Proxy :: Proxy (Count b))
1004967 elementsA = take ccols [minA .. maxA]
1005968 elementsB = take rrows [minB .. maxB]
1006969 combinations = (,) <$> elementsA <*> elementsB
src/LAoP/Matrix/Nat.hs+68−80
@@ -56,18 +56,17 @@ module LAoP.Matrix.Nat
5656
5757 -- * Constraint type synonyms
5858 Countable,
59− CountableDimensions,
59+ CountableDims,
6060 CountableN,
6161 CountableNz,
62− CountableDimensionsN,
63− FromListsN,
64− FromListsNz,
62+ CountableDimsN,
63+ FLN,
64+ FLNz,
6565 Liftable,
6666 TrivialE,
6767 TrivialP,
6868
6969 -- * Primitives
70− empty,
7170 one,
7271 join,
7372 fork,
@@ -78,11 +77,11 @@ module LAoP.Matrix.Nat
7877 I.Normalize,
7978
8079 -- * Matrix construction and conversion
81− I.FromLists,
80+ I.FL,
8281 fromLists,
8382 toLists,
8483 toList,
85− matrixBuilder,
84+ matrixBuilder',
8685 row,
8786 col,
8887 zeros,
@@ -161,38 +160,25 @@ where
161160import Data.Proxy
162161import GHC.TypeLits
163162import Control.DeepSeq
164−import qualified Control.Category as C
165163import qualified LAoP.Matrix.Internal as I
166164
167165newtype Matrix e (cols :: Nat) (rows :: Nat) = M (I.Matrix e (I.FromNat cols) (I.FromNat rows))
168166 deriving (Show, Num, Eq, Ord, NFData) via (I.Matrix e (I.FromNat cols) (I.FromNat rows))
169167
170168-- | Constraint type synonyms to keep the type signatures less convoluted
171−type Countable a = KnownNat (I.Count a)
172−type CountableDimensions a b = (Countable a, Countable b)
173−type CountableN a = KnownNat (I.Count (I.FromNat a))
174−type CountableNz a = KnownNat (I.Count (I.Normalize a))
175−type CountableDimensionsN a b = (CountableN a, CountableN b)
176−type FromListsN e a b = I.FromLists e (I.FromNat a) (I.FromNat b)
177−type FromListsNz e a b = I.FromLists e (I.Normalize a) (I.Normalize b)
178−type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
179−type TrivialE a b = I.FromNat (a + b) ~ Either (I.FromNat a) (I.FromNat b)
180−type TrivialP a b = I.FromNat (a * b) ~ I.FromNat (I.Count (I.FromNat a) * I.Count (I.FromNat b))
181−
182−-- | It isn't possible to implement the 'id' function so it's
183−-- implementation is 'undefined'. However 'comp' can be and this partial
184−-- class implementation exists just to make the code more readable.
185−--
186−-- Please use 'iden' instead.
187−instance (Num e) => C.Category (Matrix e) where
188− id = undefined
189− (.) = comp
169+type Countable a = KnownNat (I.Count a)
170+type CountableDims a b = (Countable a, Countable b)
171+type CountableN a = KnownNat (I.Count (I.FromNat a))
172+type CountableNz a = KnownNat (I.Count (I.Normalize a))
173+type CountableDimsN a b = (CountableN a, CountableN b)
174+type FLN e a b = I.FL (I.FromNat a) (I.FromNat b)
175+type FLNz e a b = I.FL (I.Normalize a) (I.Normalize b)
176+type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
177+type TrivialE a b = I.FromNat (a + b) ~ Either (I.FromNat a) (I.FromNat b)
178+type TrivialP a b = I.FromNat (a * b) ~ I.FromNat (I.Count (I.FromNat a) * I.Count (I.FromNat b))
190179
191180-- Primitives
192181
193−empty :: Matrix e 0 0
194−empty = M I.Empty
195−
196182one :: e -> Matrix e 1 1
197183one = M . I.One
198184
@@ -228,25 +214,27 @@ infixl 2 ===
228214
229215-- Construction
230216
231−fromLists :: (FromListsN e cols rows) => [[e]] -> Matrix e cols rows
217+fromLists :: (FLN e cols rows) => [[e]] -> Matrix e cols rows
232218fromLists = M . I.fromLists
233219
234−matrixBuilder ::
235− (FromListsN e cols rows, CountableN cols, CountableN rows)
220+-- | Matrix builder function. Constructs a matrix provided with
221+-- a construction function that operates with indices.
222+matrixBuilder' ::
223+ (FLN e cols rows, CountableN cols, CountableN rows)
236224 => ((Int, Int) -> e) -> Matrix e cols rows
237−matrixBuilder = M . I.matrixBuilder
225+matrixBuilder' = M . I.matrixBuilder'
238226
239−col :: (I.FromLists e () (I.FromNat rows)) => [e] -> Matrix e 1 rows
227+col :: (I.FL () (I.FromNat rows)) => [e] -> Matrix e 1 rows
240228col = M . I.col
241229
242−row :: (I.FromLists e (I.FromNat cols) ()) => [e] -> Matrix e cols 1
230+row :: (I.FL (I.FromNat cols) ()) => [e] -> Matrix e cols 1
243231row = M . I.row
244232
245233fromF' ::
246234 ( Liftable e a b,
247235 CountableN cols,
248236 CountableN rows,
249− FromListsN e rows cols
237+ FLN e rows cols
250238 ) =>
251239 (a -> b) ->
252240 Matrix e cols rows
@@ -256,7 +244,7 @@ fromF ::
256244 ( Liftable e a b,
257245 CountableNz a,
258246 CountableNz b,
259− FromListsNz e b a
247+ FLNz e b a
260248 ) =>
261249 (a -> b) ->
262250 Matrix e (I.Count a) (I.Count b)
@@ -273,21 +261,21 @@ toList (M m) = I.toList m
273261-- Zeros Matrix
274262
275263zeros ::
276− (Num e, FromListsN e cols rows, CountableN cols, CountableN rows) =>
264+ (Num e, FLN e cols rows, CountableN cols, CountableN rows) =>
277265 Matrix e cols rows
278266zeros = M I.zeros
279267
280268-- Ones Matrix
281269
282270ones ::
283− (Num e, FromListsN e cols rows, CountableN cols, CountableN rows) =>
271+ (Num e, FLN e cols rows, CountableN cols, CountableN rows) =>
284272 Matrix e cols rows
285273ones = M I.ones
286274
287275-- Const Matrix
288276
289277constant ::
290− (Num e, FromListsN e cols rows, CountableN cols, CountableN rows) =>
278+ (Num e, FLN e cols rows, CountableN cols, CountableN rows) =>
291279 e ->
292280 Matrix e cols rows
293281constant = M . I.constant
@@ -296,14 +284,14 @@ constant = M . I.constant
296284
297285bang ::
298286 forall e cols.
299− (Num e, Enum e, I.FromLists e (I.FromNat cols) (), CountableN cols) =>
287+ (Num e, Enum e, I.FL (I.FromNat cols) (), CountableN cols) =>
300288 Matrix e cols 1
301289bang = M I.bang
302290
303291-- iden Matrix
304292
305293iden ::
306− (Num e, FromListsN e cols cols, CountableN cols) =>
294+ (Num e, FLN e cols cols, CountableN cols) =>
307295 Matrix e cols cols
308296iden = M I.iden
309297
@@ -328,9 +316,9 @@ infixl 7 ./
328316
329317p1 ::
330318 ( Num e,
331− CountableDimensionsN n m,
332− FromListsN e n m,
333− FromListsN e m m,
319+ CountableDimsN n m,
320+ FLN e n m,
321+ FLN e m m,
334322 TrivialE m n
335323 ) =>
336324 Matrix e (m + n) m
@@ -338,9 +326,9 @@ p1 = M I.p1
338326
339327p2 ::
340328 ( Num e,
341− CountableDimensionsN n m,
342− FromListsN e m n,
343− FromListsN e n n,
329+ CountableDimsN n m,
330+ FLN e m n,
331+ FLN e n n,
344332 TrivialE m n
345333 ) =>
346334 Matrix e (m + n) n
@@ -350,9 +338,9 @@ p2 = M I.p2
350338
351339i1 ::
352340 ( Num e,
353− CountableDimensionsN n rows,
354− FromListsN e n rows,
355− FromListsN e rows rows,
341+ CountableDimsN n rows,
342+ FLN e n rows,
343+ FLN e rows rows,
356344 TrivialE rows n
357345 ) =>
358346 Matrix e rows (rows + n)
@@ -360,9 +348,9 @@ i1 = tr p1
360348
361349i2 ::
362350 ( Num e,
363− CountableDimensionsN rows m,
364− FromListsN e m rows,
365− FromListsN e rows rows,
351+ CountableDimsN rows m,
352+ FLN e m rows,
353+ FLN e rows rows,
366354 TrivialE m rows
367355 ) =>
368356 Matrix e rows (m + rows)
@@ -381,11 +369,11 @@ infixl 5 -|-
381369-- | Coproduct Bifunctor (Direct sum)
382370(-|-) ::
383371 ( Num e,
384− CountableDimensionsN j k,
385− FromListsN e k k,
386− FromListsN e j k,
387− FromListsN e k j,
388− FromListsN e j j,
372+ CountableDimsN j k,
373+ FLN e k k,
374+ FLN e j k,
375+ FLN e k j,
376+ FLN e j j,
389377 TrivialE n m,
390378 TrivialE k j
391379 ) =>
@@ -398,9 +386,9 @@ infixl 5 -|-
398386fstM ::
399387 forall e m k .
400388 ( Num e,
401− CountableDimensionsN m k,
389+ CountableDimsN m k,
402390 CountableN (m * k),
403− FromListsN e (m * k) m,
391+ FLN e (m * k) m,
404392 TrivialP m k
405393 ) => Matrix e (m * k) m
406394fstM = M (I.fstM @e @(I.FromNat m) @(I.FromNat k))
@@ -409,8 +397,8 @@ fstM = M (I.fstM @e @(I.FromNat m) @(I.FromNat k))
409397sndM ::
410398 forall e m k.
411399 ( Num e,
412− CountableDimensionsN k m,
413− FromListsN e (m * k) k,
400+ CountableDimsN k m,
401+ FLN e (m * k) k,
414402 CountableN (m * k),
415403 TrivialP m k
416404 ) => Matrix e (m * k) k
@@ -420,10 +408,10 @@ sndM = M (I.sndM @e @(I.FromNat m) @(I.FromNat k))
420408kr ::
421409 forall e cols a b.
422410 ( Num e,
423− CountableDimensionsN a b,
411+ CountableDimsN a b,
424412 CountableN (a * b),
425− FromListsN e (a * b) a,
426− FromListsN e (a * b) b,
413+ FLN e (a * b) a,
414+ FLN e (a * b) b,
427415 TrivialP a b
428416 ) => Matrix e cols a -> Matrix e cols b -> Matrix e cols (a * b)
429417kr a b =
@@ -437,13 +425,13 @@ infixl 4 ><
437425(><) ::
438426 forall e m p n q.
439427 ( Num e,
440− CountableDimensionsN m n,
441− CountableDimensionsN p q,
442− CountableDimensionsN (m * n) (p * q),
443− FromListsN e (m * n) m,
444− FromListsN e (m * n) n,
445− FromListsN e (p * q) p,
446− FromListsN e (p * q) q,
428+ CountableDimsN m n,
429+ CountableDimsN p q,
430+ CountableDimsN (m * n) (p * q),
431+ FLN e (m * n) m,
432+ FLN e (m * n) n,
433+ FLN e (p * q) p,
434+ FLN e (p * q) q,
447435 TrivialP m n,
448436 TrivialP p q
449437 ) => Matrix e m p -> Matrix e n q -> Matrix e (m * n) (p * q)
@@ -467,7 +455,7 @@ tr (M m) = M (I.tr m)
467455-- Selective 'select' operator
468456select ::
469457 ( Num e,
470− FromListsN e rows1 rows1,
458+ FLN e rows1 rows1,
471459 CountableN rows1,
472460 I.FromNat rows2 ~ I.FromNat rows1,
473461 I.FromNat cols1 ~ I.FromNat cols2,
@@ -480,9 +468,9 @@ select (M m) (M y) = M (I.select m y)
480468cond ::
481469 ( I.FromNat (I.Count (I.FromNat cols)) ~ I.FromNat cols,
482470 CountableN cols,
483− I.FromLists e () (I.FromNat cols),
484− I.FromLists e (I.FromNat cols) (),
485− FromListsN e cols cols,
471+ I.FL () (I.FromNat cols),
472+ I.FL (I.FromNat cols) (),
473+ FLN e cols cols,
486474 Liftable e a Bool
487475 )
488476 =>
@@ -491,10 +479,10 @@ cond p (M a) (M b) = M (I.cond p a b)
491479
492480-- Pretty print
493481
494−pretty :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> String
482+pretty :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> String
495483pretty (M m) = I.pretty m
496484
497−prettyPrint :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> IO ()
485+prettyPrint :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> IO ()
498486prettyPrint (M m) = I.prettyPrint m
499487
500488-- | Zip two matrices with a given binary function
src/LAoP/Matrix/Type.hs+143−124
@@ -1,11 +1,11 @@
11{-# LANGUAGE ConstraintKinds #-}
2+{-# LANGUAGE TypeFamilies #-}
23{-# LANGUAGE AllowAmbiguousTypes #-}
34{-# LANGUAGE DataKinds #-}
45{-# LANGUAGE DerivingVia #-}
56{-# LANGUAGE FlexibleContexts #-}
67{-# LANGUAGE FlexibleInstances #-}
78{-# LANGUAGE GADTs #-}
8−{-# LANGUAGE KindSignatures #-}
99{-# LANGUAGE MultiParamTypeClasses #-}
1010{-# LANGUAGE NoStarIsType #-}
1111{-# LANGUAGE RankNTypes #-}
@@ -58,10 +58,10 @@ module LAoP.Matrix.Type
5858
5959 -- * Constraint type aliases
6060 Countable,
61− CountableDimensions,
61+ CountableDims,
6262 CountableN,
63− CountableDimensionsN,
64− FromListsN,
63+ CountableDimsN,
64+ FLN,
6565 Liftable,
6666 Trivial,
6767 TrivialP,
@@ -71,7 +71,6 @@ module LAoP.Matrix.Type
7171 One,
7272
7373 -- * Primitives
74− empty,
7574 one,
7675 join,
7776 fork,
@@ -86,6 +85,7 @@ module LAoP.Matrix.Type
8685 fromLists,
8786 toLists,
8887 toList,
88+ matrixBuilder',
8989 matrixBuilder,
9090 row,
9191 col,
@@ -104,8 +104,8 @@ module LAoP.Matrix.Type
104104 multM,
105105
106106 -- * Selective equivalent instance function
107− selectM,
108−
107+ selectM,
108+
109109 -- * Monad equivalent instance function
110110 returnM,
111111 bindM,
@@ -113,7 +113,9 @@ module LAoP.Matrix.Type
113113 -- * Misc
114114 -- ** Get dimensions
115115 columns,
116+ columns',
116117 rows,
118+ rows',
117119
118120 -- ** Matrix Transposition
119121 tr,
@@ -181,46 +183,44 @@ where
181183import Data.Void
182184import Data.Proxy
183185import Data.Kind
184−import GHC.TypeLits
186+import GHC.TypeLits
185187import Control.DeepSeq
186188import LAoP.Utils
187−import qualified Control.Category as C
188189import qualified LAoP.Matrix.Internal as I
190+import Prelude hiding (id, (.))
189191
190192newtype Matrix e (cols :: Type) (rows :: Type) = M (I.Matrix e (I.Normalize cols) (I.Normalize rows))
191193 deriving (Show, Num, Eq, Ord, NFData) via (I.Matrix e (I.Normalize cols) (I.Normalize rows))
192194
193195-- | Constraint type synonyms to keep the type signatures less convoluted
194−type Countable a = KnownNat (I.Count a)
195−type CountableDimensions a b = (Countable a, Countable b)
196−type CountableN a = KnownNat (I.Count (I.Normalize a))
197−type CountableDimensionsN a b = (CountableN a, CountableN b)
198−type FromListsN e a b = I.FromLists e (I.Normalize a) (I.Normalize b)
199−type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
200−type Trivial a = I.Normalize (I.Normalize a) ~ I.Normalize (I.Normalize (I.Normalize a))
201−type Trivial2 a = I.Normalize a ~ I.Normalize (I.Normalize a)
202−type Trivial3 a = I.FromNat (I.Count (I.Normalize (I.Normalize a))) ~ I.Normalize (I.Normalize a)
203−type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
204−
205−-- | It isn't possible to implement the 'id' function so it's
206−-- implementation is 'undefined'. However 'comp' can be and this partial
207−-- class implementation exists just to make the code more readable.
208−--
209−-- Please use 'iden' instead.
210−instance (Num e) => C.Category (Matrix e) where
211− id = undefined
212− (.) = comp
196+type Countable a = KnownNat (I.Count a)
197+type CountableDims a b = (Countable a, Countable b)
198+type CountableN a = KnownNat (I.Count (I.Normalize a))
199+type CountableDimsN a b = (CountableN a, CountableN b)
200+type FLN a b = I.FromLists (I.Normalize a) (I.Normalize b)
201+type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
202+type Trivial a = I.Normalize (I.Normalize a) ~ I.Normalize (I.Normalize (I.Normalize a))
203+type Trivial2 a = I.Normalize a ~ I.Normalize (I.Normalize a)
204+type Trivial3 a = I.FromNat (I.Count (I.Normalize (I.Normalize a))) ~ I.Normalize (I.Normalize a)
205+type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
206+
207+-- | It is possible to implement a constrained version of the category type
208+-- class.
209+instance (Num e) => Category (Matrix e) where
210+ type Object (Matrix e) a = (FLN a a, CountableN a)
211+ id = iden
212+ (.) = comp
213213
214214-- | Bifunctor equivalent function
215215bimapM ::
216216 ( Liftable e a b,
217217 Liftable e c d,
218− CountableDimensionsN a c,
219− CountableDimensionsN b d,
220− FromListsN e d c,
221− FromListsN e b a
218+ CountableDimsN a c,
219+ CountableDimsN b d,
220+ FLN d c,
221+ FLN b a
222222 ) => (a -> b) -> (c -> d) -> Matrix e a c -> Matrix e b d
223−bimapM f g m = fromF g `comp` m `comp` tr (fromF f)
223+bimapM f g m = fromF g . m . tr (fromF f)
224224
225225-- | Zero type alias
226226type Zero = Void
@@ -230,10 +230,6 @@ type One = ()
230230
231231-- Primitives
232232
233−-- | Empty matrix constructor
234−empty :: Matrix e Zero Zero
235−empty = M I.Empty
236−
237233-- | Unit matrix constructor
238234one :: e -> Matrix e One One
239235one = M . I.One
@@ -271,37 +267,37 @@ infixl 2 ===
271267-- Functor hierarchy
272268
273269-- | Functor instance equivalent function
274−fmapM ::
270+fmapM ::
275271 ( Liftable e a b,
276− CountableDimensionsN a b,
277− FromListsN e b a
272+ CountableDimsN a b,
273+ FLN b a
278274 )
279275 =>
280276 (a -> b) -> Matrix e c a -> Matrix e c b
281−fmapM f m = fromF f `comp` m
277+fmapM f m = fromF f . m
282278
283279-- | Applicative instance equivalent 'unit' function,
284280unitM :: (Num e) => Matrix e () ()
285281unitM = one 1
286282
287283-- | Applicative instance equivalent 'unit' function,
288−multM ::
289− ( CountableDimensionsN a b,
284+multM ::
285+ ( CountableDimsN a b,
290286 CountableN (a, b),
291287 Num e,
292− FromListsN e (a, b) a,
293− FromListsN e (a, b) b,
288+ FLN (a, b) a,
289+ FLN (a, b) b,
294290 TrivialP a b
295291 ) => Matrix e c a -> Matrix e c b -> Matrix e c (a, b)
296292multM = kr
297293
298294-- | Monad instance equivalent 'return' function,
299−returnM ::
300− forall e a .
295+returnM ::
296+ forall e a .
301297 ( Num e,
302298 Enum e,
303299 Enum a,
304− FromListsN e () a,
300+ FLN () a,
305301 Countable a
306302 ) => a -> Matrix e One a
307303returnM a = col l
@@ -318,22 +314,35 @@ bindM = flip comp
318314
319315-- | Build a matrix out of a list of list of elements. Throws a runtime
320316-- error if the dimensions do not match.
321−fromLists :: (FromListsN e cols rows) => [[e]] -> Matrix e cols rows
317+fromLists :: (FLN cols rows) => [[e]] -> Matrix e cols rows
322318fromLists = M . I.fromLists
323319
324320-- | Matrix builder function. Constructs a matrix provided with
325−-- a construction function.
326−matrixBuilder ::
327− (FromListsN e cols rows, CountableDimensionsN cols rows )
321+-- a construction function that operates with indices.
322+matrixBuilder' ::
323+ (FLN cols rows, CountableDimsN cols rows )
328324 => ((Int, Int) -> e) -> Matrix e cols rows
329−matrixBuilder = M . I.matrixBuilder
325+matrixBuilder' = M . I.matrixBuilder'
326+
327+-- | Matrix builder function. Constructs a matrix provided with
328+-- a construction function that operates with arbitrary types.
329+matrixBuilder ::
330+ ( FLN a b,
331+ Enum a,
332+ Enum b,
333+ Bounded a,
334+ Bounded b,
335+ Eq a,
336+ Countable b
337+ ) => ((a, b) -> e) -> Matrix e a b
338+matrixBuilder f = M (I.matrixBuilder f)
330339
331340-- | Constructs a column vector matrix
332−col :: (FromListsN e () rows) => [e] -> Matrix e One rows
341+col :: (FLN () rows) => [e] -> Matrix e One rows
333342col = M . I.col
334343
335344-- | Constructs a row vector matrix
336−row :: (FromListsN e cols ()) => [e] -> Matrix e cols One
345+row :: (FLN cols ()) => [e] -> Matrix e cols One
337346row = M . I.row
338347
339348-- | Lifts functions to matrices with arbitrary dimensions.
@@ -342,8 +351,8 @@ row = M . I.row
342351-- types @a@ or @b@ allows.
343352fromF' ::
344353 ( Liftable e a b,
345− CountableDimensionsN cols rows,
346− FromListsN e rows cols
354+ CountableDimsN cols rows,
355+ FLN rows cols
347356 ) =>
348357 (a -> b) -> Matrix e cols rows
349358fromF' = M . I.fromF'
@@ -352,8 +361,8 @@ fromF' = M . I.fromF'
352361-- cardinality's.
353362fromF ::
354363 ( Liftable e a b,
355− CountableDimensionsN a b,
356− FromListsN e b a
364+ CountableDimsN a b,
365+ FLN b a
357366 ) =>
358367 (a -> b) -> Matrix e a b
359368fromF = M . I.fromF
@@ -361,8 +370,8 @@ fromF = M . I.fromF
361370-- | Lifts relation functions to Boolean Matrix
362371toRel ::
363372 ( Liftable (Natural 0 1) a b,
364− CountableDimensionsN a b,
365− FromListsN (Natural 0 1) b a
373+ CountableDims a b,
374+ FLN b a
366375 ) => (a -> b -> Bool) -> Matrix (Natural 0 1) a b
367376toRel = M . I.toRel
368377
@@ -380,7 +389,7 @@ toList (M m) = I.toList m
380389
381390-- | The zero matrix. A matrix wholly filled with zeros.
382391zeros ::
383− (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
392+ (Num e, FLN cols rows, CountableDimsN cols rows)
384393 => Matrix e cols rows
385394zeros = M I.zeros
386395
@@ -390,7 +399,7 @@ zeros = M I.zeros
390399--
391400-- Also known as T (Top) matrix.
392401ones ::
393− (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
402+ (Num e, FLN cols rows, CountableDimsN cols rows)
394403 => Matrix e cols rows
395404ones = M I.ones
396405
@@ -399,7 +408,7 @@ ones = M I.ones
399408-- | The constant matrix constructor. A matrix wholly filled with a given
400409-- value.
401410constant ::
402− (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
411+ (Num e, FLN cols rows, CountableDimsN cols rows)
403412 => e -> Matrix e cols rows
404413constant = M . I.constant
405414
@@ -408,19 +417,19 @@ constant = M . I.constant
408417-- | The T (Top) row vector matrix.
409418bang ::
410419 forall e cols.
411− (Num e, Enum e, FromListsN e cols (), CountableN cols) =>
420+ (Num e, Enum e, FLN cols (), CountableN cols) =>
412421 Matrix e cols One
413422bang = M I.bang
414423
415424-- | Point constant relation
416−point ::
425+point ::
417426 ( Bounded a,
418427 Enum a,
419428 Eq a,
420429 Num e,
421430 Ord e,
422431 CountableN a,
423− FromListsN e a One
432+ FLN a One
424433 ) => a -> Matrix e One a
425434point = fromF . const
426435
@@ -428,7 +437,7 @@ point = fromF . const
428437
429438-- | iden matrix
430439iden ::
431− (Num e, FromListsN e a a, CountableN a) =>
440+ (Num e, FLN a a, CountableN a) =>
432441 Matrix e a a
433442iden = M I.iden
434443{-# NOINLINE iden #-}
@@ -442,7 +451,7 @@ iden = M I.iden
442451comp :: (Num e) => Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
443452comp (M a) (M b) = M (I.comp a b)
444453{-# NOINLINE comp #-}
445−{-# RULES
454+{-# RULES
446455 "comp/iden1" forall m. comp m iden = m ;
447456 "comp/iden2" forall m. comp iden m = m
448457#-}
@@ -464,9 +473,9 @@ infixl 7 ./
464473-- | Biproduct first component projection
465474p1 ::
466475 ( Num e,
467− CountableDimensionsN n m,
468− FromListsN e n m,
469− FromListsN e m m
476+ CountableDimsN n m,
477+ FLN n m,
478+ FLN m m
470479 ) =>
471480 Matrix e (Either m n) m
472481p1 = M I.p1
@@ -474,9 +483,9 @@ p1 = M I.p1
474483-- | Biproduct second component projection
475484p2 ::
476485 ( Num e,
477− CountableDimensionsN n m,
478− FromListsN e m n,
479− FromListsN e n n
486+ CountableDimsN n m,
487+ FLN m n,
488+ FLN n n
480489 ) =>
481490 Matrix e (Either m n) n
482491p2 = M I.p2
@@ -486,9 +495,9 @@ p2 = M I.p2
486495-- | Biproduct first component injection
487496i1 ::
488497 ( Num e,
489− CountableDimensionsN n m,
490− FromListsN e n m,
491− FromListsN e m m
498+ CountableDimsN n m,
499+ FLN n m,
500+ FLN m m
492501 ) =>
493502 Matrix e m (Either m n)
494503i1 = tr p1
@@ -496,9 +505,9 @@ i1 = tr p1
496505-- | Biproduct second component injection
497506i2 ::
498507 ( Num e,
499− CountableDimensionsN n m,
500− FromListsN e m n,
501− FromListsN e n n
508+ CountableDimsN n m,
509+ FLN m n,
510+ FLN n n
502511 ) =>
503512 Matrix e n (Either m n)
504513i2 = tr p2
@@ -507,24 +516,34 @@ i2 = tr p2
507516
508517-- | Obtain the number of rows.
509518--
510−-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
511−-- dimensions in constant time.
512−--
513−-- TODO: A 'rows' function that does not need the 'KnownNat' constraint in
514−-- exchange for performance.
519+-- NOTE: The 'KnownNat' constraint is needed in order to obtain the
520+-- dimensions in constant time. For a version that doesn't require the
521+-- constraint see 'rows''.
515522rows :: (CountableN rows) => Matrix e cols rows -> Int
516523rows (M m) = I.rows m
517524
525+-- | Obtain the number of rows in an inefficient manner, but without any
526+-- constraints.
527+--
528+-- For a more efficient version see 'rows'.
529+rows' :: Matrix e cols rows -> Int
530+rows' (M m) = I.rows' m
531+
518532-- | Obtain the number of columns.
519−--
520−-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
521−-- dimensions in constant time.
522533--
523−-- TODO: A 'columns' function that does not need the 'KnownNat' constraint in
524−-- exchange for performance.
534+-- NOTE: The 'KnownNat' constraint is needed in order to obtain the
535+-- dimensions in constant time. For a version that doesn't require the
536+-- constraint see 'columns''.
525537columns :: (CountableN cols) => Matrix e cols rows -> Int
526538columns (M m) = I.columns m
527539
540+-- | Obtain the number of columns in an inefficient manner, but without any
541+-- constraints.
542+--
543+-- For a more efficient version see 'columns'.
544+columns' :: Matrix e cols rows -> Int
545+columns' (M m) = I.columns' m
546+
528547-- Coproduct Bifunctor
529548
530549infixl 5 -|-
@@ -532,11 +551,11 @@ infixl 5 -|-
532551-- | Matrix coproduct functor also known as matrix direct sum.
533552(-|-) ::
534553 ( Num e,
535− CountableDimensionsN j k,
536− FromListsN e k k,
537− FromListsN e j k,
538− FromListsN e k j,
539− FromListsN e j j
554+ CountableDimsN j k,
555+ FLN k k,
556+ FLN j k,
557+ FLN k j,
558+ FLN j j
540559 ) =>
541560 Matrix e n k ->
542561 Matrix e m j ->
@@ -546,23 +565,23 @@ infixl 5 -|-
546565-- Khatri Rao Product and projections
547566
548567-- | Khatri Rao product first component projection matrix.
549−fstM ::
568+fstM ::
550569 forall e m k .
551570 ( Num e,
552− CountableDimensionsN m k,
571+ CountableDimsN m k,
553572 CountableN (m, k),
554− FromListsN e (m, k) m,
573+ FLN (m, k) m,
555574 TrivialP m k
556575 ) => Matrix e (m, k) m
557576fstM = M (I.fstM @e @(I.Normalize m) @(I.Normalize k))
558577
559578-- | Khatri Rao product second component projection matrix.
560−sndM ::
579+sndM ::
561580 forall e m k.
562581 ( Num e,
563− CountableDimensionsN k m,
582+ CountableDimsN k m,
564583 CountableN (m, k),
565− FromListsN e (m, k) k,
584+ FLN (m, k) k,
566585 TrivialP m k
567586 ) => Matrix e (m, k) k
568587sndM = M (I.sndM @e @(I.Normalize m) @(I.Normalize k))
@@ -570,21 +589,21 @@ sndM = M (I.sndM @e @(I.Normalize m) @(I.Normalize k))
570589-- | Khatri Rao Matrix product also known as matrix pairing.
571590--
572591-- NOTE: That this is not a true categorical product, see for instance:
573−--
592+--
574593-- @
575−-- | fstM `comp` kr a b == a
594+-- | fstM . kr a b == a
576595-- kr a b ==> |
577−-- | sndM `comp` kr a b == b
596+-- | sndM . kr a b == b
578597-- @
579598--
580599-- __Emphasis__ on the implication symbol.
581600kr ::
582601 forall e cols a b.
583602 ( Num e,
584− CountableDimensionsN a b,
603+ CountableDimsN a b,
585604 CountableN (a, b),
586− FromListsN e (a, b) a,
587− FromListsN e (a, b) b,
605+ FLN (a, b) a,
606+ FLN (a, b) b,
588607 TrivialP a b
589608 ) => Matrix e cols a -> Matrix e cols b -> Matrix e cols (a, b)
590609kr a b =
@@ -600,13 +619,13 @@ infixl 4 ><
600619(><) ::
601620 forall e m p n q.
602621 ( Num e,
603− CountableDimensionsN m n,
604− CountableDimensionsN p q,
605− CountableDimensionsN (m, n) (p, q),
606− FromListsN e (m, n) m,
607− FromListsN e (m, n) n,
608− FromListsN e (p, q) p,
609− FromListsN e (p, q) q,
622+ CountableDimsN m n,
623+ CountableDimsN p q,
624+ CountableDimsN (m, n) (p, q),
625+ FLN (m, n) m,
626+ FLN (m, n) n,
627+ FLN (p, q) p,
628+ FLN (p, q) q,
610629 TrivialP m n,
611630 TrivialP p q
612631 ) => Matrix e m p -> Matrix e n q -> Matrix e (m, n) (p, q)
@@ -618,7 +637,7 @@ infixl 4 ><
618637-- Matrix abide Join Fork
619638
620639-- | Matrix "abiding" followin the 'Join'-'Fork' abide law.
621−--
640+--
622641-- Law:
623642--
624643-- @
@@ -630,7 +649,7 @@ abideJF (M m) = M (I.abideJF m)
630649-- Matrix abide Fork Join
631650
632651-- | Matrix "abiding" followin the 'Fork'-'Join' abide law.
633−--
652+--
634653-- Law:
635654--
636655-- @
@@ -649,9 +668,9 @@ tr (M m) = M (I.tr m)
649668
650669-- | Selective functors 'select' operator equivalent inspired by the
651670-- ArrowMonad solution presented in the paper.
652−selectM ::
671+selectM ::
653672 ( Num e,
654− FromListsN e b b,
673+ FLN b b,
655674 CountableN b
656675 ) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
657676selectM (M m) (M y) = M (I.select m y)
@@ -664,9 +683,9 @@ cond ::
664683 Trivial2 a,
665684 Trivial3 a,
666685 CountableN a,
667− FromListsN e () a,
668− FromListsN e a (),
669− FromListsN e a a,
686+ FLN () a,
687+ FLN a (),
688+ FLN a a,
670689 Liftable e a Bool
671690 )
672691 =>
@@ -676,11 +695,11 @@ cond p (M a) (M b) = M (I.cond p a b)
676695-- Pretty print
677696
678697-- | Matrix pretty printer
679−pretty :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> String
698+pretty :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> String
680699pretty (M m) = I.pretty m
681700
682701-- | Matrix pretty printer
683−prettyPrint :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> IO ()
702+prettyPrint :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> IO ()
684703prettyPrint (M m) = I.prettyPrint m
685704
686705-- | Zip two matrices with a given binary function
src/LAoP/Relation.hs+3−4
@@ -32,16 +32,15 @@ module LAoP.Relation
3232
3333 -- * Constraint type synonyms
3434 Countable,
35− CountableDimensions,
35+ CountableDims,
3636 CountableN,
37− CountableDimensionsN,
38− FromListsN,
37+ CountableDimsN,
38+ FLN,
3939 Liftable,
4040 Trivial,
4141 TrivialP,
4242
4343 -- * Primitives
44− empty,
4544 one,
4645 join,
4746 (|||),
src/LAoP/Relation/Internal.hs+211−200
@@ -1,3 +1,4 @@
1+{-# LANGUAGE TypeFamilies #-}
12{-# LANGUAGE ConstraintKinds #-}
23{-# LANGUAGE GADTs #-}
34{-# LANGUAGE UndecidableInstances #-}
@@ -42,16 +43,15 @@ module LAoP.Relation.Internal
4243
4344 -- * Constraint type synonyms
4445 Countable,
45− CountableDimensions,
46+ CountableDims,
4647 CountableN,
47− CountableDimensionsN,
48− FromListsN,
48+ CountableDimsN,
49+ FLN,
4950 Liftable,
5051 Trivial,
5152 TrivialP,
5253
5354 -- * Primitives
54− empty,
5555 one,
5656 join,
5757 (|||),
@@ -74,6 +74,7 @@ module LAoP.Relation.Internal
7474 toBool,
7575 pt,
7676 belongs,
77+ relationBuilder',
7778 relationBuilder,
7879 zeros,
7980 ones,
@@ -177,9 +178,9 @@ import Data.Void
177178import qualified LAoP.Matrix.Internal as I
178179import LAoP.Utils.Internal
179180import Control.DeepSeq
180−import qualified Control.Category as C
181181import Data.Bool
182182import GHC.TypeLits
183+import Prelude hiding (id, (.))
183184
184185-- | Boolean type synonym for working with boolean matrices
185186type Boolean = Natural 0 1
@@ -192,23 +193,21 @@ newtype Relation a b = R (I.Matrix Boolean (I.Normalize a) (I.Normalize b))
192193deriving instance (Read (I.Matrix Boolean (I.Normalize a) (I.Normalize b))) => Read (Relation a b)
193194
194195-- | Constraint type synonyms to keep the type signatures less convoluted
195−type Countable a = KnownNat (I.Count a)
196−type CountableDimensions a b = (Countable a, Countable b)
197−type CountableN a = KnownNat (I.Count (I.Normalize a))
198−type CountableDimensionsN a b = (CountableN a, CountableN b)
199−type FromListsN a b = I.FromLists Boolean (I.Normalize a) (I.Normalize b)
200−type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num Boolean, Ord Boolean)
201−type Trivial a = I.Normalize a ~ I.Normalize (I.Normalize a)
202−type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
203−
204−-- | It isn't possible to implement the 'id' function so it's
205−-- implementation is 'undefined'. However 'comp' can be and this partial
206−-- class implementation exists just to make the code more readable.
207−--
208−-- Please use 'iden' instead.
209−instance C.Category Relation where
210− id = undefined
211− (.) = comp
196+type Countable a = KnownNat (I.Count a)
197+type CountableDims a b = (Countable a, Countable b)
198+type CountableN a = KnownNat (I.Count (I.Normalize a))
199+type CountableDimsN a b = (CountableN a, CountableN b)
200+type FLN a b = I.FromLists (I.Normalize a) (I.Normalize b)
201+type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num Boolean, Ord Boolean)
202+type Trivial a = I.Normalize a ~ I.Normalize (I.Normalize a)
203+type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
204+
205+-- | It is possible to implement a constrained version of the category type
206+-- class.
207+instance Category Relation where
208+ type Object Relation a = (FLN a a, CountableN a)
209+ id = iden
210+ (.) = comp
212211
213212instance Num (Relation a b) where
214213 -- | Matrix addition becomes Boolean matrix disjointion
@@ -229,10 +228,6 @@ type One = ()
229228
230229-- Primitives
231230
232−-- | Empty matrix constructor
233−empty :: Relation Zero Zero
234−empty = R I.Empty
235−
236231-- | Unit matrix constructor
237232one :: Boolean -> Relation One One
238233one = R . I.One
@@ -269,14 +264,27 @@ infixl 2 ===
269264
270265-- | Build a matrix out of a list of list of elements. Throws a runtime
271266-- error if the dimensions do not match.
272−fromLists :: (FromListsN a b) => [[Boolean]] -> Relation a b
267+fromLists :: (FLN a b) => [[Boolean]] -> Relation a b
273268fromLists = R . I.fromLists
274269
275−-- | Matrix builder function. Constructs a matrix provided with
276−-- a construction function.
277−relationBuilder ::
278− (FromListsN a b, CountableDimensionsN a b) =>
270+-- | Relation builder function. Constructs a relation provided with
271+-- a construction function that operates with indices.
272+relationBuilder' ::
273+ (FLN a b, CountableDimsN a b) =>
279274 ((Int, Int) -> Boolean) -> Relation a b
275+relationBuilder' = R . I.matrixBuilder'
276+
277+-- | Relation builder function. Constructs a relation provided with
278+-- a construction function that operates with arbitrary types.
279+relationBuilder ::
280+ ( FLN a b,
281+ Enum a,
282+ Enum b,
283+ Bounded a,
284+ Bounded b,
285+ Eq a,
286+ CountableDims a b
287+ ) => ((a, b) -> Boolean) -> Relation a b
280288relationBuilder = R . I.matrixBuilder
281289
282290-- | Lifts functions to matrices with arbitrary dimensions.
@@ -285,18 +293,18 @@ relationBuilder = R . I.matrixBuilder
285293-- types @a@ or @b@ allows.
286294fromF' ::
287295 ( Liftable a b,
288− CountableDimensionsN c d,
289− FromListsN d c
296+ CountableDimsN c d,
297+ FLN d c
290298 )
291299 => (a -> b) -> Relation c d
292300fromF' f = R (I.fromFRel' f)
293301
294302-- | Lifts functions to matrices with dimensions matching @a@ and @b@
295303-- cardinality's.
296−fromF ::
304+fromF ::
297305 ( Liftable a b,
298− CountableDimensionsN a b,
299− FromListsN b a
306+ CountableDimsN a b,
307+ FLN b a
300308 )
301309 => (a -> b) -> Relation a b
302310fromF f = R (I.fromFRel f)
@@ -304,8 +312,8 @@ fromF f = R (I.fromFRel f)
304312-- | Lifts relation functions to 'Relation'
305313toRel ::
306314 ( Liftable a b,
307− CountableDimensionsN a b,
308− FromListsN b a
315+ CountableDims a b,
316+ FLN b a
309317 )
310318 => (a -> b -> Bool) -> Relation a b
311319toRel = R . I.toRel
@@ -314,9 +322,9 @@ toRel = R . I.toRel
314322fromRel ::
315323 ( Liftable a b,
316324 Eq a,
317− CountableDimensionsN a b,
318− FromListsN a One,
319− FromListsN b One
325+ CountableDimsN a b,
326+ FLN a One,
327+ FLN b One
320328 )
321329 => Relation a b -> (a -> b -> Bool)
322330fromRel r a b = pointApBool a b r
@@ -340,12 +348,12 @@ toBool r = case toList r of
340348-- | Power transpose.
341349--
342350-- Maps a relation to a set valued function.
343−pt ::
351+pt ::
344352 ( Liftable a b,
345353 Eq a,
346− CountableDimensionsN a b,
347− FromListsN a One,
348− FromListsN b One
354+ CountableDimsN a b,
355+ FLN a One,
356+ FLN b One
349357 )
350358 => Relation a b -> (a -> List b)
351359pt r a =
@@ -357,8 +365,8 @@ belongs ::
357365 ( Bounded a,
358366 Enum a,
359367 Eq a,
360− CountableDimensionsN (List a) a,
361− FromListsN a (List a)
368+ CountableDims (List a) a,
369+ FLN a (List a)
362370 )
363371 => Relation (List a) a
364372belongs = toRel elemR
@@ -370,16 +378,16 @@ belongs = toRel elemR
370378-- | The zero relation. A relation where no element of type @a@ relates
371379-- with elements of type @b@.
372380--
373−-- Also known as ⊥ (Bottom) Relation or empty Relation.
381+-- Also known as ⊥ (Bottom) Relation.
374382--
375383-- @
376−-- r ``comp`` ⊥ == ⊥ ``comp`` r == ⊥
384+-- r `.` ⊥ == ⊥ `.` r == ⊥
377385-- ⊥ ``sse`` R && R ``sse`` T == True
378386-- @
379387zeros ::
380− (FromListsN a b, CountableDimensionsN a b) =>
388+ (FLN a b, CountableDimsN a b) =>
381389 Relation a b
382−zeros = relationBuilder (const (nat 0))
390+zeros = relationBuilder' (const (nat 0))
383391
384392-- Ones Matrix
385393
@@ -392,25 +400,25 @@ zeros = relationBuilder (const (nat 0))
392400-- ⊥ ``sse`` R && R ``sse`` T == True
393401-- @
394402ones ::
395− (FromListsN a b, CountableDimensionsN a b) =>
403+ (FLN a b, CountableDimsN a b) =>
396404 Relation a b
397−ones = relationBuilder (const (nat 1))
405+ones = relationBuilder' (const (nat 1))
398406
399407-- Bang Matrix
400408
401409-- | The T (Top) row vector relation.
402410bang ::
403− (FromListsN a One, CountableN a) =>
411+ (FLN a One, CountableN a) =>
404412 Relation a One
405413bang = ones
406414
407415-- | Point constant relation
408−point ::
416+point ::
409417 ( Bounded a,
410418 Enum a,
411419 Eq a,
412420 CountableN a,
413− FromListsN a One
421+ FLN a One
414422 ) => a -> Relation One a
415423point = fromF . const
416424
@@ -419,16 +427,16 @@ point = fromF . const
419427-- | iden matrix
420428--
421429-- @
422−-- 'iden' ``comp`` r == r == r ``comp`` 'iden'
430+-- 'iden' `.` r == r == r `.` 'iden'
423431-- @
424432iden ::
425− (FromListsN a a, CountableN a) => Relation a a
426−iden = relationBuilder (bool (nat 0) (nat 1) . uncurry (==))
433+ (FLN a a, CountableN a) => Relation a a
434+iden = relationBuilder' (bool (nat 0) (nat 1) . uncurry (==))
427435
428436-- | Relational composition
429437--
430438-- @
431−-- r ``comp`` (s ``comp`` p) = (r ``comp`` s) ``comp`` p
439+-- r `.` (s `.` p) = (r `.` s) `.` p
432440-- @
433441comp :: Relation b c -> Relation a b -> Relation a c
434442comp (R a) (R b) = R (I.compRel a b)
@@ -476,7 +484,7 @@ shrunkBy r s = r `intersection` divR s (conv r)
476484-- r ``overriddenBy`` r == r
477485-- @
478486overriddenBy ::
479− ( FromListsN b b,
487+ ( FLN b b,
480488 CountableN b
481489 ) => Relation a b -> Relation a b -> Relation a b
482490overriddenBy r s = s `union` r `intersection` divR zeros (conv s)
@@ -488,11 +496,11 @@ overriddenBy r s = s `union` r `intersection` divR zeros (conv s)
488496pointAp ::
489497 ( Liftable a b,
490498 Eq a,
491− CountableDimensionsN a b,
492− FromListsN a One,
493− FromListsN b One
499+ CountableDimsN a b,
500+ FLN a One,
501+ FLN b One
494502 ) => a -> b -> Relation a b -> Relation One One
495−pointAp a b r = conv (point b) `comp` r `comp` point a
503+pointAp a b r = conv (point b) . r . point a
496504
497505-- | Relational application
498506--
@@ -500,11 +508,11 @@ pointAp a b r = conv (point b) `comp` r `comp` point a
500508pointApBool ::
501509 ( Liftable a b,
502510 Eq a,
503− CountableDimensionsN a b,
504− FromListsN a One,
505− FromListsN b One
511+ CountableDimsN a b,
512+ FLN a One,
513+ FLN b One
506514 ) => a -> b -> Relation a b -> Bool
507−pointApBool a b r = toBool $ conv (point b) `comp` r `comp` point a
515+pointApBool a b r = toBool $ conv (point b) . r . point a
508516
509517-- | Relational converse
510518--
@@ -546,8 +554,8 @@ intersection a b = a * b
546554-- @
547555-- (r ``union`` s) ``union`` t == r `'union' (s ``union`` t)
548556-- r ``union`` s ``sse`` x == r ``sse`` x && s ``sse`` x
549−-- r ``comp`` (s ``union`` t) == (r ``comp`` s) ``union`` (r ``comp`` t)
550−-- (s ``union`` t) ``comp`` r == (s ``comp`` r) ``union`` (t ``comp`` r)
557+-- r `.` (s ``union`` t) == (r `.` s) ``union`` (r `.` t)
558+-- (s ``union`` t) `.` r == (s `.` r) ``union`` (t `.` r)
551559-- @
552560union :: Relation a b -> Relation a b -> Relation a b
553561union a b = a + b
@@ -555,46 +563,46 @@ union a b = a + b
555563-- | Relation Kernel
556564--
557565-- @
558−-- 'ker' r == 'conv' r ``comp`` r
566+-- 'ker' r == 'conv' r `.` r
559567-- 'ker' r == 'img' ('conv' r)
560568-- @
561569ker :: Relation a b -> Relation a a
562−ker r = conv r `comp` r
570+ker r = conv r . r
563571
564572-- | Relation Image
565573--
566574-- @
567−-- 'img' r == r ``comp`` conv r
575+-- 'img' r == r `.` conv r
568576-- 'img' r == 'ker' ('conv' r)
569577-- @
570578img :: Relation a b -> Relation b b
571−img r = r `comp` conv r
579+img r = r . conv r
572580
573581-- | Function division. Special case of 'divS'.
574582--
575583-- NOTE: _This is only valid_ if @f@ and @g@ are 'function's, i.e. 'simple' and
576584-- 'entire'.
577585--
578−-- @'divisionF' f g == 'conv' g ``comp`` f@
586+-- @'divisionF' f g == 'conv' g `.` f@
579587divisionF :: Relation a c -> Relation b c -> Relation a b
580−divisionF f g = conv g `comp` f
588+divisionF f g = conv g . f
581589
582590-- Taxonomy of binary relations
583591
584592-- | A 'Relation' @r@ is 'simple' 'iff' @'coreflexive' ('img' r)@
585−simple :: (CountableN b, FromListsN b b) => Relation a b -> Bool
593+simple :: (CountableN b, FLN b b) => Relation a b -> Bool
586594simple = coreflexive . img
587595
588596-- | A 'Relation' @r@ is 'injective' 'iff' @'coreflexive' ('ker' r)@
589−injective :: (CountableN a, FromListsN a a) => Relation a b -> Bool
597+injective :: (CountableN a, FLN a a) => Relation a b -> Bool
590598injective = coreflexive . ker
591599
592600-- | A 'Relation' @r@ is 'entire' 'iff' @'reflexive' ('ker' r)@
593−entire :: (CountableN a, FromListsN a a) => Relation a b -> Bool
601+entire :: (CountableN a, FLN a a) => Relation a b -> Bool
594602entire = reflexive . ker
595603
596604-- | A 'Relation' @r@ is 'surjective' 'iff' @'reflexive' ('img' r)@
597−surjective :: (CountableN b, FromListsN b b) => Relation a b -> Bool
605+surjective :: (CountableN b, FLN b b) => Relation a b -> Bool
598606surjective = reflexive . img
599607
600608-- | A 'Relation' @r@ is a 'function' 'iff' @'simple' r && 'entire' r@
@@ -603,13 +611,13 @@ surjective = reflexive . img
603611-- relations:
604612--
605613-- @
606−-- f ``comp`` r ``sse`` s == r ``sse`` f ``comp`` s
607−-- r ``comp`` f ``sse`` s == r ``sse`` s ``comp`` f
614+-- f `.` r ``sse`` s == r ``sse`` f `.` s
615+-- r `.` f ``sse`` s == r ``sse`` s `.` f
608616-- @
609617function ::
610− ( CountableDimensionsN a b,
611− FromListsN a a,
612− FromListsN b b
618+ ( CountableDimsN a b,
619+ FLN a a,
620+ FLN b b
613621 )
614622 => Relation a b -> Bool
615623function r = simple r && entire r
@@ -617,7 +625,7 @@ function r = simple r && entire r
617625-- | A 'Relation' @r@ is a 'representation' 'iff' @'injective' r && 'entire' r@
618626representation ::
619627 ( CountableN a,
620− FromListsN a a
628+ FLN a a
621629 )
622630 => Relation a b -> Bool
623631representation r = injective r && entire r
@@ -625,91 +633,91 @@ representation r = injective r && entire r
625633-- | A 'Relation' @r@ is an 'abstraction' 'iff' @'surjective' r && 'simple' r@
626634abstraction ::
627635 ( CountableN b,
628− FromListsN b b
636+ FLN b b
629637 )
630638 => Relation a b -> Bool
631639abstraction r = surjective r && simple r
632640
633641-- | A 'Relation' @r@ is a 'surjection' 'iff' @'function' r && 'abstraction' r@
634642surjection ::
635− ( CountableDimensionsN a b,
636− FromListsN a a,
637− FromListsN b b
643+ ( CountableDimsN a b,
644+ FLN a a,
645+ FLN b b
638646 )
639647 => Relation a b -> Bool
640648surjection r = function r && abstraction r
641649
642650-- | A 'Relation' @r@ is a 'injection' 'iff' @'function' r && 'representation' r@
643651injection ::
644− ( CountableDimensionsN a b,
645− FromListsN a a,
646− FromListsN b b
652+ ( CountableDimsN a b,
653+ FLN a a,
654+ FLN b b
647655 )
648656 => Relation a b -> Bool
649657injection r = function r && representation r
650658
651659-- | A 'Relation' @r@ is an 'bijection' 'iff' @'injection' r && 'surjection' r@
652660bijection ::
653− ( CountableDimensionsN a b,
654− FromListsN b b,
655− FromListsN a a
661+ ( CountableDimsN a b,
662+ FLN b b,
663+ FLN a a
656664 ) => Relation a b -> Bool
657665bijection r = injection r && surjection r
658666
659667-- Properties of relations
660668
661−-- | A 'Relation' @r@ is 'reflexive' 'iff' @'iden' ``sse`` r@
662−reflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
663−reflexive r = iden <= r
669+-- | A 'Relation' @r@ is 'reflexive' 'iff' @'id' ``sse`` r@
670+reflexive :: (CountableN a, FLN a a) => Relation a a -> Bool
671+reflexive r = id <= r
664672
665−-- | A 'Relation' @r@ is 'coreflexive' 'iff' @r ``sse`` 'iden'@
666−coreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
667−coreflexive r = r <= iden
673+-- | A 'Relation' @r@ is 'coreflexive' 'iff' @r ``sse`` 'id'@
674+coreflexive :: (CountableN a, FLN a a) => Relation a a -> Bool
675+coreflexive r = r <= id
668676
669−-- | A 'Relation' @r@ is 'transitive' 'iff' @(r ``comp`` r) ``sse`` r@
677+-- | A 'Relation' @r@ is 'transitive' 'iff' @(r `.` r) ``sse`` r@
670678transitive :: Relation a a -> Bool
671−transitive r = (r `comp` r) `sse` r
679+transitive r = (r . r) `sse` r
672680
673681-- | A 'Relation' @r@ is 'symmetric' 'iff' @r == 'conv' r@
674682symmetric :: Relation a a -> Bool
675683symmetric r = r == conv r
676684
677−-- | A 'Relation' @r@ is anti-symmetric 'iff' @(r ``intersection`` 'conv' r) ``sse`` 'iden'@
678−antiSymmetric :: (CountableN a, FromListsN a a) => Relation a a -> Bool
679−antiSymmetric r = (r `intersection` conv r) `sse` iden
685+-- | A 'Relation' @r@ is anti-symmetric 'iff' @(r ``intersection`` 'conv' r) ``sse`` 'id'@
686+antiSymmetric :: (CountableN a, FLN a a) => Relation a a -> Bool
687+antiSymmetric r = (r `intersection` conv r) `sse` id
680688
681−-- | A 'Relation' @r@ is 'irreflexive' 'iff' @(r ``intersection`` 'iden') == 'zeros'@
682−irreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
683−irreflexive r = (r `intersection` iden) == zeros
689+-- | A 'Relation' @r@ is 'irreflexive' 'iff' @(r ``intersection`` 'id') == 'zeros'@
690+irreflexive :: (CountableN a, FLN a a) => Relation a a -> Bool
691+irreflexive r = (r `intersection` id) == zeros
684692
685693-- | A 'Relation' @r@ is 'connected' 'iff' @(r ``union`` 'conv' r) == 'ones'@
686−connected :: (CountableN a, FromListsN a a) => Relation a a -> Bool
694+connected :: (CountableN a, FLN a a) => Relation a a -> Bool
687695connected r = (r `union` conv r) == ones
688696
689697-- | A 'Relation' @r@ is a 'preorder' 'iff' @'reflexive' r && 'transitive' r@
690−preorder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
698+preorder :: (CountableN a, FLN a a) => Relation a a -> Bool
691699preorder r = reflexive r && transitive r
692700
693701-- | A 'Relation' @r@ is a partial-order 'iff' @'antiSymmetric' r && 'preorder' r@
694−partialOrder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
702+partialOrder :: (CountableN a, FLN a a) => Relation a a -> Bool
695703partialOrder r = antiSymmetric r && preorder r
696704
697705-- | A 'Relation' @r@ is a linear-order 'iff' @'connected' r && 'partialOrder' r@
698−linearOrder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
706+linearOrder :: (CountableN a, FLN a a) => Relation a a -> Bool
699707linearOrder r = connected r && partialOrder r
700708
701709-- | A 'Relation' @r@ is an 'equivalence' 'iff' @'symmetric' r && 'preorder' r@
702−equivalence :: (CountableN a, FromListsN a a) => Relation a a -> Bool
710+equivalence :: (CountableN a, FLN a a) => Relation a a -> Bool
703711equivalence r = symmetric r && preorder r
704712
705713-- | A 'Relation' @r@ is a partial-equivalence 'iff' @'partialOrder' r && 'equivalence' r@
706−partialEquivalence :: (CountableN a, FromListsN a a) => Relation a a -> Bool
714+partialEquivalence :: (CountableN a, FLN a a) => Relation a a -> Bool
707715partialEquivalence r = partialOrder r && equivalence r
708716
709717-- | A 'Relation' @r@ is 'difunctional' or regular wherever
710−-- @r ``comp`` 'conv' r ``comp`` r == r@
718+-- @r `.` 'conv' r `.` r == r@
711719difunctional :: Relation a b -> Bool
712−difunctional r = r `comp` conv r `comp` r == r
720+difunctional r = r . conv r . r == r
713721
714722-- Relational pairing
715723
@@ -718,27 +726,27 @@ difunctional r = r `comp` conv r `comp` r == r
718726-- NOTE: That this is not a true categorical product, see for instance:
719727--
720728-- @
721−-- | 'fstR' ``comp`` 'splitR' a b ``sse`` a
729+-- | 'fstR' `.` 'splitR' a b ``sse`` a
722730-- 'splitR' a b <=> |
723−-- | 'sndR' ``comp`` 'splitR' a b ``sse`` b
731+-- | 'sndR' `.` 'splitR' a b ``sse`` b
724732-- @
725733--
726734-- __Emphasis__ on the 'sse'.
727735--
728736-- @
729−-- 'splitR' r s ``comp`` f == 'splitR' (r ``comp`` f) (s ``comp`` f)
730−-- (R '><' S) ``comp`` 'splitR' p q == 'splitR' (r ``comp`` p) (s ``comp`` q)
731−-- 'conv' ('splitR' r s) ``comp`` 'splitR' x y == ('conv' r ``comp`` x) ``intersection`` ('conv' s ``comp`` y)
737+-- 'splitR' r s `.` f == 'splitR' (r `.` f) (s `.` f)
738+-- (R '><' S) `.` 'splitR' p q == 'splitR' (r `.` p) (s `.` q)
739+-- 'conv' ('splitR' r s) `.` 'splitR' x y == ('conv' r `.` x) ``intersection`` ('conv' s `.` y)
732740-- @
733741--
734742-- @
735743-- 'eitherR' ('splitR' r s) ('splitR' t v) == 'splitR' ('eitherR' r t) ('eitherR' s v)
736744-- @
737745splitR ::
738− ( CountableDimensionsN a b,
746+ ( CountableDimsN a b,
739747 CountableN (a, b),
740− FromListsN (a, b) a,
741− FromListsN (a, b) b,
748+ FLN (a, b) a,
749+ FLN (a, b) b,
742750 TrivialP a b
743751 )
744752 => Relation c a -> Relation c b -> Relation c (a, b)
@@ -747,13 +755,13 @@ splitR (R f) (R g) = R (I.kr f g)
747755-- | Relational pairing first component projection
748756--
749757-- @
750−-- 'fstR' ``comp`` 'splitR' r s ``sse`` r
758+-- 'fstR' `.` 'splitR' r s ``sse`` r
751759-- @
752760fstR ::
753761 forall a b .
754− ( CountableDimensionsN a b,
762+ ( CountableDimsN a b,
755763 CountableN (a, b),
756− FromListsN (a, b) a,
764+ FLN (a, b) a,
757765 TrivialP a b
758766 )
759767 => Relation (a, b) a
@@ -762,13 +770,13 @@ fstR = R (I.fstM @Boolean @(I.Normalize a) @(I.Normalize b))
762770-- | Relational pairing second component projection
763771--
764772-- @
765−-- 'sndR' ``comp`` 'splitR' r s ``sse`` s
773+-- 'sndR' `.` 'splitR' r s ``sse`` s
766774-- @
767775sndR ::
768776 forall a b .
769− ( CountableDimensionsN a b,
777+ ( CountableDimsN a b,
770778 CountableN (a, b),
771− FromListsN (a, b) b,
779+ FLN (a, b) b,
772780 TrivialP a b
773781 )
774782 => Relation (a, b) b
@@ -780,17 +788,17 @@ infixl 4 ><
780788-- | Relational pairing functor
781789--
782790-- @
783−-- r '><' s == 'splitR' (r ``comp`` fstR) (s ``comp`` sndR)
784−-- (r '><' s) ``comp`` (p '><' q) == (r ``comp`` p) '><' (s ``comp`` q)
791+-- r '><' s == 'splitR' (r `.` fstR) (s `.` sndR)
792+-- (r '><' s) `.` (p '><' q) == (r `.` p) '><' (s `.` q)
785793-- @
786794(><) ::
787− ( CountableDimensionsN a b,
788− CountableDimensionsN c d,
789− CountableDimensionsN (a, c) (b, d),
790− FromListsN (a, c) a,
791− FromListsN (a, c) c,
792− FromListsN (b, d) b,
793− FromListsN (b, d) d,
795+ ( CountableDimsN a b,
796+ CountableDimsN c d,
797+ CountableDimsN (a, c) (b, d),
798+ FLN (a, c) a,
799+ FLN (a, c) c,
800+ FLN (b, d) b,
801+ FLN (b, d) d,
794802 TrivialP a c,
795803 TrivialP b d
796804 )
@@ -802,13 +810,13 @@ infixl 4 ><
802810-- | Relational coproduct.
803811--
804812-- @
805−-- | 'eitherR' a b ``comp`` 'i1' == a
813+-- | 'eitherR' a b `.` 'i1' == a
806814-- 'eitherR' a b <=> |
807−-- | 'eitherR' a b ``comp`` 'i2' == b
815+-- | 'eitherR' a b `.` 'i2' == b
808816-- @
809817--
810818-- @
811−-- 'eitherR' r s ``comp`` 'conv' ('eitherR' t u) == (r ``comp`` 'conv' t) ``union`` (s ``comp`` 'conv' u)
819+-- 'eitherR' r s `.` 'conv' ('eitherR' t u) == (r `.` 'conv' t) ``union`` (s `.` 'conv' u)
812820-- @
813821--
814822-- @
@@ -820,13 +828,13 @@ eitherR = join
820828-- | Relational coproduct first component injection
821829--
822830-- @
823−-- 'img' 'i1' ``union`` 'img' 'i2' == 'iden'
824−-- 'i1' ``comp`` 'i2' = 'zeros'
831+-- 'img' 'i1' ``union`` 'img' 'i2' == 'id'
832+-- 'i1' `.` 'i2' = 'zeros'
825833-- @
826834i1 ::
827− ( CountableDimensionsN a b,
828− FromListsN b a,
829− FromListsN a a
835+ ( CountableDimsN a b,
836+ FLN b a,
837+ FLN a a
830838 )
831839 => Relation a (Either a b)
832840i1 = R I.i1
@@ -834,13 +842,13 @@ i1 = R I.i1
834842-- | Relational coproduct second component injection
835843--
836844-- @
837−-- 'img' 'i1' ``union`` 'img' 'i2' == 'iden'
838−-- 'i1' ``comp`` 'i2' = 'zeros'
845+-- 'img' 'i1' ``union`` 'img' 'i2' == 'id'
846+-- 'i1' `.` 'i2' = 'zeros'
839847-- @
840848i2 ::
841− ( CountableDimensionsN a b,
842− FromListsN a b,
843− FromListsN b b
849+ ( CountableDimsN a b,
850+ FLN a b,
851+ FLN b b
844852 )
845853 => Relation b (Either a b)
846854i2 = R I.i2
@@ -850,14 +858,14 @@ infixl 5 -|-
850858-- | Relational coproduct functor.
851859--
852860-- @
853−-- r '-|-' s == 'eitherR' ('i1' ``comp`` r) ('i2' ``comp`` s)
861+-- r '-|-' s == 'eitherR' ('i1' `.` r) ('i2' `.` s)
854862-- @
855863(-|-) ::
856− ( CountableDimensionsN b d,
857− FromListsN b b,
858− FromListsN d b,
859− FromListsN b d,
860− FromListsN d d
864+ ( CountableDimsN b d,
865+ FLN b b,
866+ FLN d b,
867+ FLN b d,
868+ FLN d d
861869 )
862870 => Relation a b -> Relation c d -> Relation (Either a c) (Either b d)
863871(-|-) (R a) (R b) = R ((I.-|-) a b)
@@ -870,20 +878,20 @@ infixl 5 -|-
870878-- 'trans'/'untrans';
871879-- more-over, where each particular attribute is placed (input/output) is irrelevant.
872880trans ::
873− ( CountableDimensionsN a b,
881+ ( CountableDimsN a b,
874882 CountableN c,
875− CountableDimensionsN (a, b) (c, b),
876− FromListsN (c, b) c,
877− FromListsN (c, b) b,
878− FromListsN (a, b) a,
879− FromListsN (a, b) b,
883+ CountableDimsN (a, b) (c, b),
884+ FLN (c, b) c,
885+ FLN (c, b) b,
886+ FLN (a, b) a,
887+ FLN (a, b) b,
880888 Trivial (a, b),
881889 Trivial (c, b),
882890 TrivialP a b,
883891 TrivialP c b
884892 )
885893 => Relation (a, b) c -> Relation a (c, b)
886−trans r = splitR r sndR `comp` conv fstR
894+trans r = splitR r sndR . conv fstR
887895
888896-- | Relational 'untrans'
889897--
@@ -891,107 +899,110 @@ trans r = splitR r sndR `comp` conv fstR
891899-- 'trans'/'untrans';
892900-- more-over, where each particular attribute is placed (input/output) is irrelevant.
893901untrans ::
894− ( CountableDimensionsN a b,
902+ ( CountableDimsN a b,
895903 CountableN c,
896− CountableDimensionsN (a, b) (c, b),
897− FromListsN (c, b) c,
898− FromListsN (c, b) b,
899− FromListsN (a, b) b,
900− FromListsN (a, b) a,
904+ CountableDimsN (a, b) (c, b),
905+ FLN (c, b) c,
906+ FLN (c, b) b,
907+ FLN (a, b) b,
908+ FLN (a, b) a,
901909 Trivial (a, b),
902910 Trivial (c, b),
903911 TrivialP a b,
904912 TrivialP c b
905913 )
906914 => Relation a (c, b) -> Relation (a, b) c
907−untrans s = fstR `comp` conv (splitR (conv s) sndR)
915+untrans s = fstR . conv (splitR (conv s) sndR)
908916
909917-- | Transforms predicate @p@ into a correflexive relation.
910918--
911919-- @
912−-- 'predR' ('const' True) == 'iden'
920+-- 'predR' ('const' True) == 'id'
913921-- 'predR' ('const' False) == 'zeros'
914922-- @
915923--
916924-- @
917−-- 'predR' q ``comp`` 'predR' p == 'predR' q ``union`` 'predR' p
925+-- 'predR' q `.` 'predR' p == 'predR' q ``union`` 'predR' p
918926-- @
919927predR ::
920928 ( Bounded a,
921929 Enum a,
930+ Countable a,
922931 CountableN a,
923− FromListsN a a,
924− FromListsN Bool a
932+ FLN a a,
933+ FLN Bool a
925934 )
926935 => Relation a Bool -> Relation a a
927−predR p = iden `intersection` divisionF (fromF (const True)) p
936+predR p = id `intersection` divisionF (fromF (const True)) p
928937
929938-- | Equalizes functions @f@ and @g@.
930939-- That is, @'equalizer' f g@ is the largest coreflexive
931940-- that restricts @g@ so that @f@ and @g@ yield the same outputs.
932941--
933942-- @
934−-- 'equalizer' r r == 'iden'
943+-- 'equalizer' r r == 'id'
935944-- 'equalizer' ('point' True) ('point' False) == 'zeros'
936945-- @
937946equalizer ::
938947 ( CountableN a,
939− FromListsN a a
948+ FLN a a
940949 )
941950 => Relation a b -> Relation a b -> Relation a a
942−equalizer f g = iden `intersection` divisionF f g
951+equalizer f g = id `intersection` divisionF f g
943952
944953-- | Relational conditional guard.
945954--
946955-- @
947−-- 'guard' p = 'i2' ``overriddenBy`` 'i1' ``comp`` 'predR' p
956+-- 'guard' p = 'i2' ``overriddenBy`` 'i1' `.` 'predR' p
948957-- @
949−guard ::
958+guard ::
950959 ( Bounded b,
951960 Enum b,
952961 CountableN b,
953− FromListsN b b,
954− FromListsN Bool b
962+ Countable b,
963+ FLN b b,
964+ FLN Bool b
955965 ) => Relation b Bool -> Relation b (Either b b)
956966guard p = conv (eitherR (predR p) (predR (negate p)))
957967
958968-- | Relational McCarthy's conditional.
959−cond ::
969+cond ::
960970 ( Bounded b,
961971 Enum b,
972+ Countable b,
962973 CountableN b,
963− FromListsN b b,
964− FromListsN Bool b
965− )
974+ FLN b b,
975+ FLN Bool b
976+ )
966977 => Relation b Bool -> Relation b c -> Relation b c -> Relation b c
967−cond p r s = eitherR r s `comp` guard p
978+cond p r s = eitherR r s . guard p
968979
969980-- | Relational domain.
970981--
971982-- For injective relations, 'domain' and 'ker'nel coincide,
972−-- since @'ker' r ``sse`` 'iden'@ in such situations.
983+-- since @'ker' r ``sse`` 'id'@ in such situations.
973984domain ::
974985 ( CountableN a,
975− FromListsN a a
986+ FLN a a
976987 ) => Relation a b -> Relation a a
977−domain r = ker r `intersection` iden
988+domain r = ker r `intersection` id
978989
979990-- | Relational range.
980991--
981992-- For functions, 'range' and 'img' (image) coincide,
982−-- since @'img' f ``sse`` 'iden'@ for any @f@.
993+-- since @'img' f ``sse`` id@ for any @f@.
983994range ::
984995 ( CountableN b,
985− FromListsN b b
996+ FLN b b
986997 ) => Relation a b -> Relation b b
987−range r = img r `intersection` iden
998+range r = img r `intersection` id
988999
9891000-- Relation pretty print
9901001
9911002-- | Relation pretty printing
992−pretty :: (CountableDimensionsN a b) => Relation a b -> String
1003+pretty :: (CountableDimsN a b) => Relation a b -> String
9931004pretty (R a) = I.pretty a
9941005
9951006-- | Relation pretty printing
996−prettyPrint :: (CountableDimensionsN a b) => Relation a b -> IO ()
1007+prettyPrint :: (CountableDimsN a b) => Relation a b -> IO ()
9971008prettyPrint (R a) = I.prettyPrint a
src/LAoP/Utils.hs+4−1
@@ -96,7 +96,10 @@ module LAoP.Utils
9696 coerceNat3,
9797
9898 -- * List data type
99− List (..)
99+ List (..),
100+
101+ -- * Category type-class
102+ Category(..)
100103 )
101104where
102105
src/LAoP/Utils/Internal.hs+28−2
@@ -1,9 +1,9 @@
1+{-# LANGUAGE TypeFamilies #-}
12{-# LANGUAGE DeriveGeneric #-}
23{-# LANGUAGE TypeApplications #-}
34{-# LANGUAGE DataKinds #-}
45{-# LANGUAGE FlexibleInstances #-}
56{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6−{-# LANGUAGE KindSignatures #-}
77{-# LANGUAGE ScopedTypeVariables #-}
88
99module LAoP.Utils.Internal
@@ -19,7 +19,10 @@ module LAoP.Utils.Internal
1919 coerceNat3,
2020
2121 -- * 'List' data type
22− List (..)
22+ List (..),
23+
24+ -- * Category type class
25+ Category(..)
2326 )
2427where
2528
@@ -30,6 +33,9 @@ import Data.Maybe
3033import GHC.TypeLits
3134import Control.DeepSeq
3235import GHC.Generics
36+import Data.Kind
37+import Prelude hiding (id, (.))
38+import qualified Prelude
3339
3440-- | Wrapper around 'Int's that have a restrictive semantic associated.
3541-- A value of type @'Natural' n m@ can only be instanciated with some 'Int'
@@ -168,3 +174,23 @@ instance
168174 fromEnum (L x) =
169175 let as = [minBound .. maxBound]
170176 in fromMaybe (error "Does not exist") $ elemIndex x (powerset as)
177+
178+-- | Constrained category instance
179+class Category k where
180+ type Object k o :: Constraint
181+ type Object k o = ()
182+ id :: Object k a => k a a
183+ (.) :: k b c -> k a b -> k a c
184+
185+{-# RULES
186+"identity/left" forall p .
187+ id . p = p
188+"identity/right" forall p .
189+ p . id = p
190+"association" forall p q r .
191+ (p . q) . r = p . (q . r)
192+ #-}
193+
194+instance Category (->) where
195+ id = Prelude.id
196+ (.) = (Prelude..)
stack-8.8.3.yamlnew file+1
@@ -0,0 +1 @@
1+resolver: lts-15.5
stack.yaml+1−66
@@ -1,66 +1 @@
1−# This file was automatically generated by 'stack init'
2−#
3−# Some commonly used options have been documented as comments in this file.
4−# For advanced use and comprehensive documentation of the format, please see:
5−# https://docs.haskellstack.org/en/stable/yaml_configuration/
6−
7−# Resolver to choose a 'specific' stackage snapshot or a compiler version.
8−# A snapshot resolver dictates the compiler version and the set of packages
9−# to be used for project dependencies. For example:
10−#
11−# resolver: lts-3.5
12−# resolver: nightly-2015-09-21
13−# resolver: ghc-7.10.2
14−#
15−# The location of a snapshot can be provided as a file or url. Stack assumes
16−# a snapshot provided as a file might change, whereas a url resource does not.
17−#
18−# resolver: ./custom-snapshot.yaml
19−# resolver: https://example.com/snapshots/2018-01-01.yaml
20−resolver: lts-14.18
21−
22−# User packages to be built.
23−# Various formats can be used as shown in the example below.
24−#
25−# packages:
26−# - some-directory
27−# - https://example.com/foo/bar/baz-0.0.2.tar.gz
28−# subdirs:
29−# - auto-update
30−# - wai
31−packages:
32−- .
33−# Dependency packages to be pulled from upstream that are not in the resolver.
34−# These entries can reference officially published versions as well as
35−# forks / in-progress versions pinned to a git hash. For example:
36−#
37−# extra-deps:
38−# - acme-missiles-0.3
39−# - git: https://github.com/commercialhaskell/stack.git
40−# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
41−#
42−# extra-deps: []
43−
44−# Override default flag values for local packages and extra-deps
45−# flags: {}
46−
47−# Extra package databases containing global packages
48−# extra-package-dbs: []
49−
50−# Control whether we use the GHC we find on the path
51−# system-ghc: true
52−#
53−# Require a specific version of stack, using version ranges
54−# require-stack-version: -any # Default
55−# require-stack-version: ">=2.1"
56−#
57−# Override the architecture used by stack, especially useful on Windows
58−# arch: i386
59−# arch: x86_64
60−#
61−# Extra directories used by stack for building
62−# extra-include-dirs: [/path/to/dir]
63−# extra-lib-dirs: [/path/to/dir]
64−#
65−# Allow a newer minor version of GHC than the snapshot specifies
66−# compiler-check: newer-minor
1+resolver: lts-14.3
stack.yaml.lock+4−4
@@ -6,7 +6,7 @@
66packages: []
77snapshots:
88- completed:
9− size: 524789
10− url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/14/18.yaml
11− sha256: 646be71223e08234131c6989912e6011e01b9767bc447b6d466a35e14360bdf2
12− original: lts-14.18
9+ size: 523878
10+ url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/14/3.yaml
11+ sha256: 470c46c27746a48c7c50f829efc0cf00112787a7804ee4ac7a27754658f6d92c
12+ original: lts-14.3
app/Quantum.hs → test/Examples/Quantum.hsrenamed+6−4
@@ -1,8 +1,10 @@
11{-# LANGUAGE StandaloneDeriving #-}
2−module Quantum where
2+module Examples.Quantum where
33
4+import LAoP.Utils
45import LAoP.Matrix.Type
56import Data.Complex
7+import Prelude hiding (id, (.))
68
79deriving instance Ord a => Ord (Complex a)
810
@@ -11,7 +13,7 @@ xor (False, b) = b
1113xor (True, b) = not b
1214
1315ker :: Num e => Matrix e a b -> Matrix e a a
14−ker m = tr m `comp` m
16+ker m = tr m . m
1517
1618cnot :: Matrix (Complex Double) (Bool, Bool) (Bool, Bool)
1719cnot = kr fstM (fromF xor)
@@ -19,11 +21,11 @@ cnot = kr fstM (fromF xor)
1921ccnot :: (Num e, Ord e) => Matrix e ((Bool, Bool), Bool) ((Bool, Bool), Bool)
2022ccnot = kr fstM (fromF f)
2123 where
22− f = xor . (tp (uncurry (&&)) id)
24+ f = xor . tp (uncurry (&&)) id
2325 tp f g (a,b) = (f a, g b)
2426
2527had :: Matrix (Complex Double) Bool Bool
2628had = (1/sqrt 2) .| fromLists [[1, 1], [1, -1]]
2729
2830bell :: Matrix (Complex Double) (Bool, Bool) (Bool, Bool)
29−bell = cnot `comp` (had >< iden)
31+bell = cnot . (had >< iden)
app/Examples.hs → test/Examples/Readme.hsrenamed+25−10
@@ -1,11 +1,10 @@
11{-# LANGUAGE GADTs #-}
22{-# LANGUAGE DeriveGeneric #-}
33{-# LANGUAGE FlexibleContexts #-}
4−{-# LANGUAGE TypeOperators #-}
54{-# LANGUAGE TypeApplications #-}
65{-# LANGUAGE DataKinds #-}
76
8−module Examples
7+module Examples.Readme
98 ( exec
109 )
1110 where
@@ -17,8 +16,7 @@ import LAoP.Dist
1716import GHC.TypeLits
1817import Data.Coerce
1918import qualified GHC.Generics as G
20−import Control.Category hiding (id)
21−import Prelude hiding ((.))
19+import Prelude hiding (id, (.))
2220
2321-- Monty Hall Problem
2422data Outcome = Win | Lose
@@ -67,17 +65,34 @@ data R = No | Yes
6765 deriving (Bounded, Enum, Eq, Show, G.Generic)
6866
6967rain :: Matrix Double () R
70−rain = col [0.8, 0.2]
68+rain = matrixBuilder gen
69+ where
70+ gen (_, No) = 0.8
71+ gen (_, Yes) = 0.2
7172
7273sprinkler :: Matrix Double R S
73−sprinkler = fromLists [[0.6, 0.99], [0.4, 0.01]]
74+sprinkler = matrixBuilder gen
75+ where
76+ gen (No, Off) = 0.6
77+ gen (No, On) = 0.4
78+ gen (Yes, Off) = 0.99
79+ gen (Yes, On) = 0.01
7480
7581grass :: Matrix Double (S, R) G
76−grass = fromLists [[1, 0.2, 0.1, 0.01], [0, 0.8, 0.9, 0.99]]
82+grass = matrixBuilder gen
83+ where
84+ gen ((Off, No), Dry) = 1
85+ gen ((Off, Yes), Dry) = 0.2
86+ gen ((On, No), Dry) = 0.1
87+ gen ((On, Yes), Dry) = 0.01
88+ gen ((Off, No), Wet) = 0
89+ gen ((Off, Yes), Wet) = 0.8
90+ gen ((On, No), Wet) = 0.9
91+ gen ((On, Yes), Wet) = 0.99
7792
78−tag f = kr f iden
93+tag f = kr f id
7994
80−state g s r = tag g `comp` tag s `comp` r
95+state g s r = tag g . tag s . r
8196
8297grass_wet :: Matrix Double () (G, (S, R)) -> Matrix Double One One
8398grass_wet state = row [0,1] . fstM . state
@@ -156,7 +171,7 @@ exec = do
156171 putStrLn "Monty Hall Problem solution:"
157172 prettyPrint (secondChoice . firstChoice)
158173 putStrLn "\n Sum of dices probability:"
159− prettyPrint (sumSSM `comp` kr die die)
174+ prettyPrint (sumSSM . kr die die)
160175 putStrLn "\n Conditional dice throw:"
161176 prettyPrint conditionalThrows
162177 putStrLn "\n Checking that the last result is indeed a distribution: "
app/Spreadsheets.hs → test/Examples/Spreadsheets.hsrenamed+5−4
@@ -1,10 +1,11 @@
11{-# LANGUAGE DeriveGeneric #-}
22
3−module Spreadsheets
4− where
3+module Examples.Spreadsheets
54
5+import LAoP.Utils
66import LAoP.Matrix.Type
77import GHC.Generics
8+import Prelude hiding (id, (.))
89
910data Student = Student1 | Student2 | Student3 | Student4
1011 deriving (Eq, Show, Enum, Bounded, Generic)
@@ -36,10 +37,10 @@ xls :: Matrix Float Question One
3637 -> Matrix Float (Either Question Results) (Either One Student)
3738xls w m t = join (fork w m) (fork zeros r)
3839 where
39− rExam = m `comp` tr w
40+ rExam = m . tr w
4041 rTest = tr t
4142 rFinal = rTest `maxPW` rExam
42− r = (rExam `comp` tr exam) + (rTest `comp` tr test) + (rFinal `comp` tr final)
43+ r = (rExam . tr exam) + (rTest . tr test) + (rFinal . tr final)
4344
4445-- | Overloaded, point-wise 'max' function
4546maxPW :: Ord e => Matrix e a b -> Matrix e a b -> Matrix e a b
test/Spec.hs+7−1
@@ -1,2 +1,8 @@
1+module Main (main) where
2+
3+import qualified Examples.Readme as RD
4+
15main :: IO ()
2−main = putStrLn "Test suite not yet implemented"
6+main = do
7+ putStrLn ("Testing if README works" :: String)
8+ RD.exec