on 77aae98 help sign in
31 files changed+903−1011
since splitsnapshots
unifiedsplit
.ghc.environment.x86_64-linux-8.6.5+17 .github/workflows/ci.yml−43 .gitignore+2−54 .travis.yml−47 CHANGELOG.md−17 ChangeLog.md+3 LICENSE+26−17 README.md+30−34 Setup.hs+2 benchmark/Main.hs → app/Benchmarks.hs+13−11 test/Examples/Readme.hs → app/Examples.hs+10−25 app/Main.hs+7 test/Examples/Quantum.hs → app/Quantum.hs+4−6 test/Examples/Spreadsheets.hs → app/Spreadsheets.hs+4−5 appveyor.yml−34 hackage.sh+10 laop.cabal−89 package.yaml+57 src/LAoP/Dist.hs+2−2 src/LAoP/Dist/Internal.hs+43−44 src/LAoP/Matrix/Internal.hs+199−151 src/LAoP/Matrix/Nat.hs+77−63 src/LAoP/Matrix/Type.hs+123−128 src/LAoP/Relation.hs+4−3 src/LAoP/Relation/Internal.hs+196−193 src/LAoP/Utils.hs+1−4 src/LAoP/Utils/Internal.hs+2−28 stack-8.8.3.yaml−1 stack.yaml+66−1 stack.yaml.lock+4−4 test/Spec.hs+1−7
.ghc.environment.x86_64-linux-8.6.5new file+17
@@ -0,0 +1,17 @@
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.ymldeleted−43
@@ -1,43 +0,0 @@
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+2−54
@@ -1,55 +1,3 @@
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
251.stack-work/
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
2+laop.cabal
3+*~
.travis.ymldeleted−47
@@ -1,47 +0,0 @@
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.mddeleted−17
@@ -1,17 +0,0 @@
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.mdnew file+3
@@ -0,0 +1,3 @@
1+# Changelog for laop
2+
3+## Unreleased changes
LICENSE+26−17
@@ -1,21 +1,30 @@
1−MIT License
1+Copyright Armando Santos (c) 2019
22
3−Copyright (c) 2020 Armando Santos
3+All rights reserved.
44
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:
5+Redistribution and use in source and binary forms, with or without
6+modification, are permitted provided that the following conditions are met:
117
12−The above copyright notice and this permission notice shall be included in all
13−copies or substantial portions of the Software.
8+ * Redistributions of source code must retain the above copyright
9+ notice, this list of conditions and the following disclaimer.
1410
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.
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.
README.md+30−34
@@ -1,11 +1,5 @@
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−
93The LAoP discipline generalises relations and functions treating them as
104Boolean matrices and in turn consider these as arrows.
115
@@ -16,38 +10,40 @@ motivation behind the library, the underlying theory, and implementation details
1610This module offers many of the combinators mentioned in the work of
1711[Macedo (2012)](https://repositorium.sdum.uminho.pt/handle/1822/22894) and [Oliveira (2012)](https://pdfs.semanticscholar.org/ccf5/27fa9179081223bffe8067edd81948644fc0.pdf).
1812
19−See the package in hackage [here](https://hackage.haskell.org/package/laop-0.1.1.0)
20−
21−A Functional Pearl has been written and can be regarded as the [reference document](https://github.com/bolt12/tymfgg-pearl) for this library.
22−
23−## Features
24−
25−This library offers 3 main matrix programming modules:
13+See the package in hackage [here](https://hackage.haskell.org/package/laop-0.1.0.5)
2614
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;
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).
3016
31−There's also an experimental module that uses matrices to represent probability
32−distributions.
17+A Functional Pearl is also on its way, hopefully will be the reference document for this library.
3318
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
19+## Features
4920
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).
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.
5147
5248## Notes
5349
Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
benchmark/Main.hs → app/Benchmarks.hsrenamed+13−11
@@ -8,28 +8,30 @@
88{-# LANGUAGE AllowAmbiguousTypes #-}
99{-# LANGUAGE ScopedTypeVariables #-}
1010
11−module Main (main) where
11+module Benchmarks
12+ ( benchmark
13+ )
14+ where
1215
1316import LAoP.Dist.Internal
1417import LAoP.Utils
15−import LAoP.Matrix.Type hiding (CountableN, Countable, FLN)
16−import qualified LAoP.Matrix.Type as T (FLN)
18+import LAoP.Matrix.Type hiding (CountableN, Countable, FromListsN)
19+import qualified LAoP.Matrix.Type as T (FromListsN)
1720import Criterion.Main
1821import Control.DeepSeq
1922import Test.QuickCheck
2023import GHC.TypeLits
2124import Data.Proxy
22−import Prelude hiding (id, (.))
2325
2426selectM2 ::
2527 ( Num e,
26− T.FLN b b,
28+ T.FromListsN e b b,
2729 CountableN b
2830 ) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
2931selectM2 m y = join y iden `comp` m
3032
3133selectD2 ::
32− ( FLN b b,
34+ ( FromListsN b b,
3335 CountableN b
3436 ) => Dist (Either a b) -> Matrix Prob a b -> Dist b
3537selectD2 (D d) m = D (join m iden `comp` d)
@@ -37,7 +39,7 @@ selectD2 (D d) m = D (join m iden `comp` d)
3739-- Composition with iden
3840compId m = comp iden m
3941
40−randomDist :: forall a . (Countable a, FLN () a) => Gen (Dist a)
42+randomDist :: forall a . (Countable a, FromListsN () a) => Gen (Dist a)
4143randomDist = do
4244 let size = fromInteger (natVal (Proxy :: Proxy (Count a)))
4345 l <- vectorOf size (arbitrary :: Gen Prob)
@@ -46,7 +48,7 @@ randomDist = do
4648 m = fromLists lr
4749 return (D m)
4850
49−randomMatrix :: forall a b . (CountableDims a b, FLN a b) => Gen (Matrix Prob a b)
51+randomMatrix :: forall a b . (CountableDimensions a b, FromListsN a b) => Gen (Matrix Prob a b)
5052randomMatrix = do
5153 let cols = fromInteger (natVal (Proxy :: Proxy (Count a)))
5254 rows = fromInteger (natVal (Proxy :: Proxy (Count b)))
@@ -105,7 +107,7 @@ normalize3 as l = let s = sum l
105107 probs = map (/ s) l
106108 in zip as probs
107109
108−randomDistF :: forall a b . (CountableDims a b, CoArbitrary a, Arbitrary b) => Gen (Dist' (a -> b))
110+randomDistF :: forall a b . (CountableDimensions a b, CoArbitrary a, Arbitrary b) => Gen (Dist' (a -> b))
109111randomDistF = do
110112 let a = fromInteger (natVal (Proxy :: Proxy (Count a)))
111113 b = fromInteger (natVal (Proxy :: Proxy (Count b)))
@@ -144,8 +146,8 @@ setupEnv2 = do
144146 distList2 <- generate (resize 1 (randomDistF @(Natural 0 100) @(Natural 0 100)))
145147 return (m21, m40, dist, dist2, distList1, distList2)
146148
147−main :: IO ()
148−main = defaultMain [
149+benchmark :: IO ()
150+benchmark = defaultMain [
149151 env setupEnv $ \ ~(m11, m12, m21, m22, m31, m32) -> bgroup "Matrix Composition" [
150152 bgroup "10x10" [
151153 bench "WHNF - 10x10" $ whnf (comp m11) m12
test/Examples/Readme.hs → app/Examples.hsrenamed+10−25
@@ -1,10 +1,11 @@
11{-# LANGUAGE GADTs #-}
22{-# LANGUAGE DeriveGeneric #-}
33{-# LANGUAGE FlexibleContexts #-}
4+{-# LANGUAGE TypeOperators #-}
45{-# LANGUAGE TypeApplications #-}
56{-# LANGUAGE DataKinds #-}
67
7−module Examples.Readme
8+module Examples
89 ( exec
910 )
1011 where
@@ -16,7 +17,8 @@ import LAoP.Dist
1617import GHC.TypeLits
1718import Data.Coerce
1819import qualified GHC.Generics as G
19−import Prelude hiding (id, (.))
20+import Control.Category hiding (id)
21+import Prelude hiding ((.))
2022
2123-- Monty Hall Problem
2224data Outcome = Win | Lose
@@ -65,34 +67,17 @@ data R = No | Yes
6567 deriving (Bounded, Enum, Eq, Show, G.Generic)
6668
6769rain :: Matrix Double () R
68−rain = matrixBuilder gen
69− where
70− gen (_, No) = 0.8
71− gen (_, Yes) = 0.2
70+rain = col [0.8, 0.2]
7271
7372sprinkler :: Matrix Double R S
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
73+sprinkler = fromLists [[0.6, 0.99], [0.4, 0.01]]
8074
8175grass :: Matrix Double (S, R) G
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
76+grass = fromLists [[1, 0.2, 0.1, 0.01], [0, 0.8, 0.9, 0.99]]
9277
93−tag f = kr f id
78+tag f = kr f iden
9479
95−state g s r = tag g . tag s . r
80+state g s r = tag g `comp` tag s `comp` r
9681
9782grass_wet :: Matrix Double () (G, (S, R)) -> Matrix Double One One
9883grass_wet state = row [0,1] . fstM . state
@@ -171,7 +156,7 @@ exec = do
171156 putStrLn "Monty Hall Problem solution:"
172157 prettyPrint (secondChoice . firstChoice)
173158 putStrLn "\n Sum of dices probability:"
174− prettyPrint (sumSSM . kr die die)
159+ prettyPrint (sumSSM `comp` kr die die)
175160 putStrLn "\n Conditional dice throw:"
176161 prettyPrint conditionalThrows
177162 putStrLn "\n Checking that the last result is indeed a distribution: "
app/Main.hsnew file+7
@@ -0,0 +1,7 @@
1+module Main where
2+
3+import Examples
4+import Benchmarks
5+
6+main :: IO ()
7+main = benchmark
test/Examples/Quantum.hs → app/Quantum.hsrenamed+4−6
@@ -1,10 +1,8 @@
11{-# LANGUAGE StandaloneDeriving #-}
2−module Examples.Quantum where
2+module Quantum where
33
4−import LAoP.Utils
54import LAoP.Matrix.Type
65import Data.Complex
7−import Prelude hiding (id, (.))
86
97deriving instance Ord a => Ord (Complex a)
108
@@ -13,7 +11,7 @@ xor (False, b) = b
1311xor (True, b) = not b
1412
1513ker :: Num e => Matrix e a b -> Matrix e a a
16−ker m = tr m . m
14+ker m = tr m `comp` m
1715
1816cnot :: Matrix (Complex Double) (Bool, Bool) (Bool, Bool)
1917cnot = kr fstM (fromF xor)
@@ -21,11 +19,11 @@ cnot = kr fstM (fromF xor)
2119ccnot :: (Num e, Ord e) => Matrix e ((Bool, Bool), Bool) ((Bool, Bool), Bool)
2220ccnot = kr fstM (fromF f)
2321 where
24− f = xor . tp (uncurry (&&)) id
22+ f = xor . (tp (uncurry (&&)) id)
2523 tp f g (a,b) = (f a, g b)
2624
2725had :: Matrix (Complex Double) Bool Bool
2826had = (1/sqrt 2) .| fromLists [[1, 1], [1, -1]]
2927
3028bell :: Matrix (Complex Double) (Bool, Bool) (Bool, Bool)
31−bell = cnot . (had >< iden)
29+bell = cnot `comp` (had >< iden)
test/Examples/Spreadsheets.hs → app/Spreadsheets.hsrenamed+4−5
@@ -1,11 +1,10 @@
11{-# LANGUAGE DeriveGeneric #-}
22
3−module Examples.Spreadsheets
3+module Spreadsheets
4+ where
45
5−import LAoP.Utils
66import LAoP.Matrix.Type
77import GHC.Generics
8−import Prelude hiding (id, (.))
98
109data Student = Student1 | Student2 | Student3 | Student4
1110 deriving (Eq, Show, Enum, Bounded, Generic)
@@ -37,10 +36,10 @@ xls :: Matrix Float Question One
3736 -> Matrix Float (Either Question Results) (Either One Student)
3837xls w m t = join (fork w m) (fork zeros r)
3938 where
40− rExam = m . tr w
39+ rExam = m `comp` tr w
4140 rTest = tr t
4241 rFinal = rTest `maxPW` rExam
43− r = (rExam . tr exam) + (rTest . tr test) + (rFinal . tr final)
42+ r = (rExam `comp` tr exam) + (rTest `comp` tr test) + (rFinal `comp` tr final)
4443
4544-- | Overloaded, point-wise 'max' function
4645maxPW :: Ord e => Matrix e a b -> Matrix e a b -> Matrix e a b
appveyor.ymldeleted−34
@@ -1,34 +0,0 @@
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
hackage.shnew file+10
@@ -0,0 +1,10 @@
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.cabaldeleted−89
@@ -1,89 +0,0 @@
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.yamlnew file+57
@@ -0,0 +1,57 @@
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− CountableDimsN,
43− FLN,
42+ CountableDimensionsN,
43+ FromListsN,
4444 Liftable,
4545 TrivialP,
4646
src/LAoP/Dist/Internal.hs+43−44
@@ -16,8 +16,8 @@ module LAoP.Dist.Internal
1616
1717 Countable,
1818 CountableN,
19− CountableDimsN,
20− FLN,
19+ CountableDimensionsN,
20+ FromListsN,
2121 Liftable,
2222 TrivialP,
2323
@@ -43,8 +43,7 @@ module LAoP.Dist.Internal
4343 )
4444 where
4545
46−import LAoP.Matrix.Type hiding (TrivialP, Countable, CountableDims, CountableN, CountableDimsN, Liftable, FLN)
47−import Prelude hiding (id, (.))
46+import LAoP.Matrix.Type hiding (TrivialP, Countable, CountableDimensions, CountableN, CountableDimensionsN, Liftable, FromListsN)
4847import qualified LAoP.Matrix.Internal as I
4948import LAoP.Utils
5049import GHC.TypeLits
@@ -62,18 +61,18 @@ newtype Dist a = D (Matrix Prob () a)
6261 deriving (Show, Num, Eq, Ord, NFData) via (Matrix Prob () a)
6362
6463-- | Constraint type synonyms to keep the type signatures less convoluted
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)
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)
7170
7271-- | Functor instance
7372fmapD ::
7473 ( Liftable a b,
75− CountableDimsN a b,
76− FLN b a
74+ CountableDimensionsN a b,
75+ FromListsN b a
7776 )
7877 =>
7978 (a -> b) -> Dist a -> Dist b
@@ -85,17 +84,17 @@ unitD = D (one 1)
8584
8685-- | Applicative/Monoidal instance 'mult' function
8786multD ::
88− ( CountableDimsN a b,
87+ ( CountableDimensionsN a b,
8988 CountableN (a, b),
90− FLN (a, b) a,
91− FLN (a, b) b,
89+ FromListsN (a, b) a,
90+ FromListsN (a, b) b,
9291 TrivialP a b
9392 ) => Dist a -> Dist b -> Dist (a, b)
9493multD (D a) (D b) = D (kr a b)
9594
9695-- | Selective instance function
9796selectD ::
98− ( FLN b b,
97+ ( FromListsN b b,
9998 CountableN b
10099 ) => Dist (Either a b) -> Matrix Prob a b -> Dist b
101100selectD (D d) m = D (selectM d m)
@@ -104,17 +103,17 @@ selectD (D d) m = D (selectM d m)
104103-- functions to apply to a given argument;
105104branchD ::
106105 ( Num e,
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
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
118117 )
119118 => Dist (Either a b) -> Matrix Prob a c -> Matrix Prob b c -> Dist c
120119branchD x l r = f x `selectD` g l `selectD` r
@@ -124,11 +123,11 @@ branchD x l r = f x `selectD` g l `selectD` r
124123
125124-- | Branch on a Boolean value, skipping unnecessary computations.
126125ifD ::
127− ( CountableDimsN a (Either () a),
128− FLN a a,
129− FLN a (),
130− FLN () a,
131− FLN (Either () a) a
126+ ( CountableDimensionsN a (Either () a),
127+ FromListsN a a,
128+ FromListsN a (),
129+ FromListsN () a,
130+ FromListsN (Either () a) a
132131 )
133132 => Dist Bool -> Dist a -> Dist a -> Dist a
134133ifD x (D t) (D e) = branchD x' t e
@@ -136,7 +135,7 @@ ifD x (D t) (D e) = branchD x' t e
136135 x' = bool (Right ()) (Left ()) `fmapD` x
137136
138137-- | Monad instance 'return' function
139−returnD :: forall a . (Enum a, FLN () a, Countable a) => a -> Dist a
138+returnD :: forall a . (Enum a, FromListsN () a, Countable a) => a -> Dist a
140139returnD a = D (col l)
141140 where
142141 i = fromInteger $ natVal (Proxy :: Proxy (Count a))
@@ -151,7 +150,7 @@ bindD (D d) m = D (m `comp` d)
151150(??) ::
152151 ( Enum a,
153152 Countable a,
154− FLN () a
153+ FromListsN () a
155154 ) => (a -> Bool) -> Dist a -> Prob
156155(??) p d =
157156 let l = toValues d
@@ -161,11 +160,11 @@ bindD (D d) m = D (m `comp` d)
161160-- Distribution Construction
162161
163162-- | Constructs a Bernoulli distribution
164−choose :: (FLN () a) => Prob -> Dist a
163+choose :: (FromListsN () a) => Prob -> Dist a
165164choose prob = D (col [prob, 1 - prob])
166165
167166-- | Creates a distribution given a shape function
168−shape :: (FLN () a) => (Prob -> Prob) -> [a] -> Dist a
167+shape :: (FromListsN () a) => (Prob -> Prob) -> [a] -> Dist a
169168shape _ [] = error "Probability.shape: empty list"
170169shape f xs =
171170 let incr = 1 / fromIntegral (length xs - 1)
@@ -173,23 +172,23 @@ shape f xs =
173172 in fromFreqs (zip xs ps)
174173
175174-- | Constructs a Linear distribution
176−linear :: (FLN () a) => [a] -> Dist a
175+linear :: (FromListsN () a) => [a] -> Dist a
177176linear = shape id
178177
179178-- | Constructs an Uniform distribution
180−uniform :: (FLN () a) => [a] -> Dist a
179+uniform :: (FromListsN () a) => [a] -> Dist a
181180uniform = shape (const 1)
182181
183182-- | Constructs an Negative Exponential distribution
184−negExp :: (FLN () a) => [a] -> Dist a
183+negExp :: (FromListsN () a) => [a] -> Dist a
185184negExp = shape (\x -> exp (-x))
186185
187186-- | Constructs an Normal distribution
188−normal :: (FLN () a) => [a] -> Dist a
187+normal :: (FromListsN () a) => [a] -> Dist a
189188normal = shape (normalCurve 0.5 0.5)
190189
191190-- | Transforms a 'Dist' into a list of pairs.
192−toValues :: forall a . (Enum a, Countable a, FLN () a) => Dist a -> [(a, Prob)]
191+toValues :: forall a . (Enum a, Countable a, FromListsN () a) => Dist a -> [(a, Prob)]
193192toValues (D d) =
194193 let rows = fromInteger (natVal (Proxy :: Proxy (Count a)))
195194 probs = toList d
@@ -197,7 +196,7 @@ toValues (D d) =
197196 in res
198197
199198-- | Pretty a distribution
200−prettyDist :: forall a. (Show a, Enum a, Countable a, FLN () a) => Dist a -> String
199+prettyDist :: forall a. (Show a, Enum a, Countable a, FromListsN () a) => Dist a -> String
201200prettyDist d =
202201 let values = sortBy (\(a, p1) (b, p2) -> compare p2 p1) (toValues @a d)
203202 w = maximum (map (length . show . fst) values)
@@ -209,12 +208,12 @@ prettyDist d =
209208 showR n x = show x ++ " "
210209
211210-- | Pretty Print a distribution
212−prettyPrintDist :: forall a . (Show a, Enum a, Countable a, FLN () a) => Dist a -> IO ()
211+prettyPrintDist :: forall a . (Show a, Enum a, Countable a, FromListsN () a) => Dist a -> IO ()
213212prettyPrintDist = putStrLn . prettyDist @a
214213
215214-- Auxiliary functions
216215
217−fromFreqs :: (FLN () a) => [(a,Prob)] -> Dist a
216+fromFreqs :: (FromListsN () a) => [(a,Prob)] -> Dist a
218217fromFreqs xs = D (col (map (\(x,p) -> p/q) xs))
219218 where q = sum $ map snd xs
220219
src/LAoP/Matrix/Internal.hs+199−151
@@ -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,23 +43,14 @@ 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−
6252 -- * Primitives
53+ empty,
6354 one,
6455 join,
6556 fork,
@@ -86,9 +77,7 @@ module LAoP.Matrix.Internal
8677 -- * Misc
8778 -- ** Get dimensions
8879 columns,
89− columns',
9080 rows,
91− rows',
9281
9382 -- ** Matrix Transposition
9483 tr,
@@ -130,7 +119,6 @@ module LAoP.Matrix.Internal
130119
131120 -- | Note that given the restrictions imposed it is not possible to
132121 -- implement the standard type classes present in standard Haskell.
133−
134122 -- *** Matrix pairing projections
135123 fstM,
136124 sndM,
@@ -176,17 +164,17 @@ import Data.Kind
176164import Data.List
177165import Data.Maybe
178166import Data.Proxy
179−import Data.Typeable
180167import Data.Void
181168import GHC.TypeLits
182169import Data.Type.Equality
183170import GHC.Generics
184171import Control.DeepSeq
185−import Prelude hiding (id, (.))
186−import qualified Prelude (id, (.))
172+import Control.Category
173+import Prelude hiding ((.))
187174
188175-- | LAoP (Linear Algebra of Programming) Inductive Matrix definition.
189176data Matrix e cols rows where
177+ Empty :: Matrix e Void Void
190178 One :: e -> Matrix e () ()
191179 Join :: Matrix e a rows -> Matrix e b rows -> Matrix e (Either a b) rows
192180 Fork :: Matrix e cols a -> Matrix e cols b -> Matrix e cols (Either a b)
@@ -216,6 +204,7 @@ type family Count (d :: Type) :: Nat where
216204--
217205-- Thanks to Li-Yao Xia this type family is super fast.
218206type family FromNat (n :: Nat) :: Type where
207+ FromNat 0 = Void
219208 FromNat 1 = ()
220209 FromNat n = FromNat' (Mod n 2 == 0) (FromNat (Div n 2))
221210
@@ -232,26 +221,29 @@ type family Normalize (d :: Type) :: Type where
232221-- | Constraint type synonyms to keep the type signatures less convoluted
233222type Countable a = KnownNat (Count a)
234223type CountableN a = KnownNat (Count (Normalize a))
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)
224+type CountableDimensions a b = (Countable a, Countable b)
225+type CountableDimensionsN a b = (CountableN a, CountableN b)
226+type FromListsN e a b = FromLists e (Normalize a) (Normalize b)
239227type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
240228type Trivial a = FromNat (Count a) ~ a
241229
242−-- | It is possible to implement a constrained version of the category type
243−-- class.
230+-- | It isn't possible to implement the 'id' function so it's
231+-- implementation is 'undefined'. However 'comp' can be and this partial
232+-- class implementation exists just to make the code more readable.
233+--
234+-- Please use 'iden' instead.
244235instance (Num e) => Category (Matrix e) where
245− type Object (Matrix e) a = (FL a a, Countable a)
246− id = iden
247− (.) = comp
236+ id = undefined
237+ (.) = comp
248238
249239instance NFData e => NFData (Matrix e cols rows) where
240+ rnf Empty = ()
250241 rnf (One e) = rnf e
251242 rnf (Join a b) = rnf a `seq` rnf b
252243 rnf (Fork a b) = rnf a `seq` rnf b
253244
254245instance Eq e => Eq (Matrix e cols rows) where
246+ Empty == Empty = True
255247 (One a) == (One b) = a == b
256248 (Join a b) == (Join c d) = a == c && b == d
257249 (Fork a b) == (Fork c d) = a == c && b == d
@@ -259,21 +251,25 @@ instance Eq e => Eq (Matrix e cols rows) where
259251 x@(Join _ _) == y@(Fork _ _) = abideJF x == y
260252
261253instance Num e => Num (Matrix e cols rows) where
254+
262255 a + b = zipWithM (+) a b
263256
264257 a - b = zipWithM (-) a b
265258
266259 a * b = zipWithM (*) a b
267260
261+ abs Empty = Empty
268262 abs (One a) = One (abs a)
269263 abs (Join a b) = Join (abs a) (abs b)
270264 abs (Fork a b) = Fork (abs a) (abs b)
271265
266+ signum Empty = Empty
272267 signum (One a) = One (signum a)
273268 signum (Join a b) = Join (signum a) (signum b)
274269 signum (Fork a b) = Fork (signum a) (signum b)
275270
276271instance Ord e => Ord (Matrix e cols rows) where
272+ Empty <= Empty = True
277273 (One a) <= (One b) = a <= b
278274 (Join a b) <= (Join c d) = (a <= c) && (b <= d)
279275 (Fork a b) <= (Fork c d) = (a <= c) && (b <= d)
@@ -282,6 +278,10 @@ instance Ord e => Ord (Matrix e cols rows) where
282278
283279-- Primitives
284280
281+-- | Empty matrix constructor
282+empty :: Matrix e Void Void
283+empty = Empty
284+
285285-- | Unit matrix constructor
286286one :: e -> Matrix e () ()
287287one = One
@@ -312,39 +312,40 @@ infixl 2 ===
312312--
313313-- Given that it is not possible to branch on types at the term level type
314314-- classes are needed very much like an inductive definition but on types.
315−class FromLists cols rows where
315+class FromLists e cols rows where
316316 -- | Build a matrix out of a list of list of elements. Throws a runtime
317317 -- error if the dimensions do not match.
318318 fromLists :: [[e]] -> Matrix e cols rows
319319
320−instance FromLists () () where
320+instance FromLists e Void Void where
321+ fromLists [] = Empty
322+ fromLists _ = error "Wrong dimensions"
323+
324+instance {-# OVERLAPPING #-} FromLists e () () where
321325 fromLists [[e]] = One e
322326 fromLists _ = error "Wrong dimensions"
323327
324−instance (FromLists cols ()) => FromLists (Either () cols) () where
328+instance {-# OVERLAPPING #-} (FromLists e cols ()) => FromLists e (Either () cols) () where
325329 fromLists [h : t] = Join (One h) (fromLists [t])
326330 fromLists _ = error "Wrong dimensions"
327331
328−instance {-# OVERLAPPABLE #-}
329− (FromLists a (), FromLists b (), Countable a) => FromLists (Either a b) () where
332+instance {-# OVERLAPPABLE #-} (FromLists e a (), FromLists e b (), Countable a) => FromLists e (Either a b) () where
330333 fromLists [l] =
331334 let rowsA = fromInteger (natVal (Proxy :: Proxy (Count a)))
332335 in Join (fromLists [take rowsA l]) (fromLists [drop rowsA l])
333336 fromLists _ = error "Wrong dimensions"
334337
335−instance (FromLists () rows) => FromLists () (Either () rows) where
338+instance {-# OVERLAPPING #-} (FromLists e () rows) => FromLists e () (Either () rows) where
336339 fromLists ([h] : t) = Fork (One h) (fromLists t)
337340 fromLists _ = error "Wrong dimensions"
338341
339−instance {-# OVERLAPPABLE #-}
340− (FromLists () a, FromLists () b, Countable a) => FromLists () (Either a b) where
341− fromLists l@([_] : _) =
342+instance {-# OVERLAPPABLE #-} (FromLists e () a, FromLists e () b, Countable a) => FromLists e () (Either a b) where
343+ fromLists l@([_] : _) =
342344 let rowsA = fromInteger (natVal (Proxy :: Proxy (Count a)))
343345 in Fork (fromLists (take rowsA l)) (fromLists (drop rowsA l))
344346 fromLists _ = error "Wrong dimensions"
345347
346−instance (FromLists (Either a b) c, FromLists (Either a b) d, Countable c)
347− => FromLists (Either a b) (Either c d) where
348+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
348349 fromLists l@(h : t) =
349350 let lh = length h
350351 rowsC = fromInteger (natVal (Proxy :: Proxy (Count c)))
@@ -357,8 +358,8 @@ instance (FromLists (Either a b) c, FromLists (Either a b) d, Countable c)
357358-- a construction function that operates with indices.
358359matrixBuilder' ::
359360 forall e cols rows.
360− ( FL cols rows,
361− CountableDims cols rows
361+ ( FromLists e cols rows,
362+ CountableDimensions cols rows
362363 ) => ((Int, Int) -> e) -> Matrix e cols rows
363364matrixBuilder' f =
364365 let c = fromInteger $ natVal (Proxy :: Proxy (Count cols))
@@ -370,28 +371,24 @@ matrixBuilder' f =
370371-- a construction function that operates with arbitrary types.
371372matrixBuilder ::
372373 forall e a b.
373− ( FLN a b,
374+ ( FromListsN e a b,
374375 Enum a,
375376 Enum b,
376377 Bounded a,
377378 Bounded b,
378379 Eq a,
379− Countable b
380+ CountableDimensionsN a b
380381 ) => ((a, b) -> e) -> Matrix e (Normalize a) (Normalize b)
381382matrixBuilder 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)
383+ let positions = [(a, b) | a <- [minBound .. maxBound], b <- [minBound .. maxBound]]
384+ in fromLists . map (map f) . groupBy (\(x, _) (w, _) -> x == w) $ positions
388385
389386-- | Constructs a column vector matrix
390−col :: (FL () rows) => [e] -> Matrix e () rows
387+col :: (FromLists e () rows) => [e] -> Matrix e () rows
391388col = fromLists . map (: [])
392389
393390-- | Constructs a row vector matrix
394−row :: (FL cols ()) => [e] -> Matrix e cols ()
391+row :: (FromLists e cols ()) => [e] -> Matrix e cols ()
395392row = fromLists . (: [])
396393
397394-- | Lifts functions to matrices with arbitrary dimensions.
@@ -401,8 +398,8 @@ row = fromLists . (: [])
401398fromF' ::
402399 forall a b cols rows e.
403400 ( Liftable e a b,
404− CountableDims cols rows,
405− FL rows cols
401+ CountableDimensions cols rows,
402+ FromLists e rows cols
406403 ) =>
407404 (a -> b) ->
408405 Matrix e cols rows
@@ -430,17 +427,35 @@ fromF' f =
430427fromF ::
431428 forall a b e.
432429 ( Liftable e a b,
433− CountableDimsN a b,
434− FLN b a
430+ CountableDimensionsN a b,
431+ FromListsN e b a
435432 ) =>
436433 (a -> b) ->
437434 Matrix e (Normalize a) (Normalize b)
438−fromF = fromF'
435+fromF f =
436+ let minA = minBound @a
437+ maxA = maxBound @a
438+ minB = minBound @b
439+ maxB = maxBound @b
440+ ccols = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize a)))
441+ rrows = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize b)))
442+ elementsA = take ccols [minA .. maxA]
443+ elementsB = take rrows [minB .. maxB]
444+ combinations = (,) <$> elementsA <*> elementsB
445+ combAp = map snd . sort . map (\(a, b) -> if f a == b
446+ then ((fromEnum a, fromEnum b), 1)
447+ else ((fromEnum a, fromEnum b), 0)) $ combinations
448+ mList = buildList combAp rrows
449+ in tr $ fromLists mList
450+ where
451+ buildList [] _ = []
452+ buildList l r = take r l : buildList (drop r l) r
439453
440454-- Conversion
441455
442456-- | Converts a matrix to a list of lists of elements.
443457toLists :: Matrix e cols rows -> [[e]]
458+toLists Empty = []
444459toLists (One e) = [[e]]
445460toLists (Fork l r) = toLists l ++ toLists r
446461toLists (Join l r) = zipWith (++) (toLists l) (toLists r)
@@ -452,7 +467,7 @@ toList = concat . toLists
452467-- Zeros Matrix
453468
454469-- | The zero matrix. A matrix wholly filled with zeros.
455−zeros :: (Num e, FL cols rows, CountableDims cols rows) => Matrix e cols rows
470+zeros :: (Num e, FromLists e cols rows, CountableDimensions cols rows) => Matrix e cols rows
456471zeros = matrixBuilder' (const 0)
457472
458473-- Ones Matrix
@@ -460,20 +475,20 @@ zeros = matrixBuilder' (const 0)
460475-- | The ones matrix. A matrix wholly filled with ones.
461476--
462477-- Also known as T (Top) matrix.
463−ones :: (Num e, FL cols rows, CountableDims cols rows) => Matrix e cols rows
478+ones :: (Num e, FromLists e cols rows, CountableDimensions cols rows) => Matrix e cols rows
464479ones = matrixBuilder' (const 1)
465480
466481-- Const Matrix
467482
468483-- | The constant matrix constructor. A matrix wholly filled with a given
469484-- value.
470−constant :: (Num e, FL cols rows, CountableDims cols rows) => e -> Matrix e cols rows
485+constant :: (Num e, FromLists e cols rows, CountableDimensions cols rows) => e -> Matrix e cols rows
471486constant e = matrixBuilder' (const e)
472487
473488-- Bang Matrix
474489
475490-- | The T (Top) row vector matrix.
476−bang :: forall e cols. (Num e, Enum e, FL cols (), Countable cols) => Matrix e cols ()
491+bang :: forall e cols. (Num e, Enum e, FromLists e cols (), Countable cols) => Matrix e cols ()
477492bang =
478493 let c = fromInteger $ natVal (Proxy :: Proxy (Count cols))
479494 in fromLists [take c [1, 1 ..]]
@@ -481,7 +496,7 @@ bang =
481496-- iden Matrix
482497
483498-- | iden matrix.
484−iden :: forall e cols . (Num e, FL cols cols, Countable cols) => Matrix e cols cols
499+iden :: (Num e, FromLists e cols cols, Countable cols) => Matrix e cols cols
485500iden = matrixBuilder' (bool 0 1 . uncurry (==))
486501{-# NOINLINE iden #-}
487502
@@ -492,12 +507,13 @@ iden = matrixBuilder' (bool 0 1 . uncurry (==))
492507-- This definition takes advantage of divide-and-conquer and fusion laws
493508-- from LAoP.
494509comp :: (Num e) => Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
510+comp Empty Empty = Empty
495511comp (One a) (One b) = One (a * b)
496512comp (Join a b) (Fork c d) = comp a c + comp b d -- Divide-and-conquer law
497513comp (Fork a b) c = Fork (comp a c) (comp b c) -- Fork fusion law
498514comp c (Join a b) = Join (comp c a) (comp c b) -- Join fusion law
499515{-# NOINLINE comp #-}
500−{-# RULES
516+{-# RULES
501517 "comp/iden1" forall m. comp m iden = m ;
502518 "comp/iden2" forall m. comp iden m = m
503519#-}
@@ -507,6 +523,7 @@ comp c (Join a b) = Join (comp c a) (comp c b) -- Join fusion law
507523infixl 7 .|
508524-- | Scalar multiplication of matrices.
509525(.|) :: Num e => e -> Matrix e cols rows -> Matrix e cols rows
526+(.|) _ Empty = Empty
510527(.|) e (One a) = One (e * a)
511528(.|) e (Join a b) = Join (e .| a) (e .| b)
512529(.|) e (Fork a b) = Fork (e .| a) (e .| b)
@@ -516,6 +533,7 @@ infixl 7 .|
516533infixl 7 ./
517534-- | Scalar multiplication of matrices.
518535(./) :: Fractional e => Matrix e cols rows -> e -> Matrix e cols rows
536+(./) Empty _ = Empty
519537(./) (One a) e = One (a / e)
520538(./) (Join a b) e = Join (a ./ e) (b ./ e)
521539(./) (Fork a b) e = Fork (a ./ e) (b ./ e)
@@ -523,59 +541,45 @@ infixl 7 ./
523541-- Projections
524542
525543-- | Biproduct first component projection
526−p1 :: (Num e, CountableDims n m, FL n m, FL m m) => Matrix e (Either m n) m
527−p1 = join id zeros
544+p1 :: (Num e, CountableDimensions n m, FromLists e n m, FromLists e m m) => Matrix e (Either m n) m
545+p1 = join iden zeros
528546
529547-- | Biproduct second component projection
530−p2 :: (Num e, CountableDims n m, FL m n, FL n n) => Matrix e (Either m n) n
531−p2 = join zeros id
548+p2 :: (Num e, CountableDimensions n m, FromLists e m n, FromLists e n n) => Matrix e (Either m n) n
549+p2 = join zeros iden
532550
533551-- Injections
534552
535553-- | Biproduct first component injection
536−i1 :: (Num e, CountableDims n m, FL n m, FL m m) => Matrix e m (Either m n)
554+i1 :: (Num e, CountableDimensions n m, FromLists e n m, FromLists e m m) => Matrix e m (Either m n)
537555i1 = tr p1
538556
539557-- | Biproduct second component injection
540−i2 :: (Num e, CountableDims n m, FL m n, FL n n) => Matrix e n (Either m n)
558+i2 :: (Num e, CountableDimensions n m, FromLists e m n, FromLists e n n) => Matrix e n (Either m n)
541559i2 = tr p2
542560
543561-- Dimensions
544562
545563-- | Obtain the number of rows.
546564--
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''.
565+-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
566+-- dimensions in constant time.
567+--
568+-- TODO: A 'rows' function that does not need the 'KnownNat' constraint in
569+-- exchange for performance.
550570rows :: forall e cols rows. (Countable rows) => Matrix e cols rows -> Int
551571rows _ = fromInteger $ natVal (Proxy :: Proxy (Count rows))
552572
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−
562573-- | Obtain the number of columns.
574+--
575+-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
576+-- dimensions in constant time.
563577--
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''.
578+-- TODO: A 'columns' function that does not need the 'KnownNat' constraint in
579+-- exchange for performance.
567580columns :: forall e cols rows. (Countable cols) => Matrix e cols rows -> Int
568581columns _ = fromInteger $ natVal (Proxy :: Proxy (Count cols))
569582
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−
579583-- Coproduct Bifunctor
580584
581585infixl 5 -|-
@@ -584,11 +588,11 @@ infixl 5 -|-
584588(-|-) ::
585589 forall e n k m j.
586590 ( Num e,
587− CountableDims j k,
588− FL k k,
589− FL j k,
590− FL k j,
591− FL j j
591+ CountableDimensions j k,
592+ FromLists e k k,
593+ FromLists e j k,
594+ FromLists e k j,
595+ FromLists e j j
592596 ) =>
593597 Matrix e n k ->
594598 Matrix e m j ->
@@ -601,8 +605,8 @@ infixl 5 -|-
601605fstM ::
602606 forall e m k .
603607 ( Num e,
604− CountableDims k m,
605− FL (Normalize (m, k)) m,
608+ CountableDimensions k m,
609+ FromLists e (Normalize (m, k)) m,
606610 CountableN (m, k)
607611 ) => Matrix e (Normalize (m, k)) m
608612fstM = matrixBuilder' f
@@ -616,8 +620,8 @@ fstM = matrixBuilder' f
616620sndM ::
617621 forall e m k .
618622 ( Num e,
619− CountableDims k m,
620− FL (Normalize (m, k)) k,
623+ CountableDimensions k m,
624+ FromLists e (Normalize (m, k)) k,
621625 CountableN (m, k)
622626 ) => Matrix e (Normalize (m, k)) k
623627sndM = matrixBuilder' f
@@ -630,7 +634,7 @@ sndM = matrixBuilder' f
630634-- | Khatri Rao Matrix product also known as matrix pairing.
631635--
632636-- NOTE: That this is not a true categorical product, see for instance:
633−--
637+--
634638-- @
635639-- | fstM . kr a b == a
636640-- kr a b ==> |
@@ -641,10 +645,10 @@ sndM = matrixBuilder' f
641645kr ::
642646 forall e cols a b.
643647 ( Num e,
644− CountableDims a b,
648+ CountableDimensions a b,
645649 CountableN (a, b),
646− FL (Normalize (a, b)) a,
647− FL (Normalize (a, b)) b
650+ FromLists e (Normalize (a, b)) a,
651+ FromLists e (Normalize (a, b)) b
648652 ) => Matrix e cols a -> Matrix e cols b -> Matrix e cols (Normalize (a, b))
649653kr a b =
650654 let fstM' = fstM @e @a @b
@@ -659,14 +663,14 @@ infixl 4 ><
659663(><) ::
660664 forall e m p n q.
661665 ( Num e,
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− )
666+ CountableDimensions m n,
667+ CountableDimensions p q,
668+ CountableDimensionsN (m, n) (p, q),
669+ FromLists e (Normalize (m, n)) m,
670+ FromLists e (Normalize (m, n)) n,
671+ FromLists e (Normalize (p, q)) p,
672+ FromLists e (Normalize (p, q)) q
673+ )
670674 => Matrix e m p -> Matrix e n q -> Matrix e (Normalize (m, n)) (Normalize (p, q))
671675(><) a b =
672676 let fstM' = fstM @e @m @n
@@ -684,6 +688,7 @@ infixl 4 ><
684688-- @
685689abideJF :: Matrix e cols rows -> Matrix e cols rows
686690abideJF (Join (Fork a c) (Fork b d)) = Fork (Join (abideJF a) (abideJF b)) (Join (abideJF c) (abideJF d)) -- Join-Fork abide law
691+abideJF Empty = Empty
687692abideJF (One e) = One e
688693abideJF (Join a b) = Join (abideJF a) (abideJF b)
689694abideJF (Fork a b) = Fork (abideJF a) (abideJF b)
@@ -697,6 +702,7 @@ abideJF (Fork a b) = Fork (abideJF a) (abideJF b)
697702-- @
698703abideFJ :: Matrix e cols rows -> Matrix e cols rows
699704abideFJ (Fork (Join a b) (Join c d)) = Join (Fork (abideFJ a) (abideFJ c)) (Fork (abideFJ b) (abideFJ d)) -- Fork-Join abide law
705+abideFJ Empty = Empty
700706abideFJ (One e) = One e
701707abideFJ (Join a b) = Join (abideFJ a) (abideFJ b)
702708abideFJ (Fork a b) = Fork (abideFJ a) (abideFJ b)
@@ -705,6 +711,7 @@ abideFJ (Fork a b) = Fork (abideFJ a) (abideFJ b)
705711
706712-- | Matrix transposition.
707713tr :: Matrix e cols rows -> Matrix e rows cols
714+tr Empty = Empty
708715tr (One e) = One e
709716tr (Join a b) = Fork (tr a) (tr b)
710717tr (Fork a b) = Join (tr a) (tr b)
@@ -713,32 +720,32 @@ tr (Fork a b) = Join (tr a) (tr b)
713720
714721-- | Selective functors 'select' operator equivalent inspired by the
715722-- ArrowMonad solution presented in the paper.
716−select :: (Num e, FL b b, Countable b) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
723+select :: (Num e, FromLists e b b, Countable b) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
717724select (Fork a b) y = y . a + b -- Divide-and-conquer law
718725select (Join (Fork a c) (Fork b d)) y = join (y . a + c) (y . b + d) -- Pattern matching + DnC law
719−select m y = join y id . m
726+select m y = join y iden . m
720727
721728branch ::
722729 ( Num e,
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
730+ CountableDimensions a b,
731+ CountableDimensions c (Either b c),
732+ FromLists e c b,
733+ FromLists e a b,
734+ FromLists e a a,
735+ FromLists e b b,
736+ FromLists e c c,
737+ FromLists e b a,
738+ FromLists e b c,
739+ FromLists e (Either b c) b,
740+ FromLists e (Either b c) c
734741 )
735742 => Matrix e cols (Either a b) -> Matrix e a c -> Matrix e b c -> Matrix e cols c
736743branch x l r = f x `select` g l `select` r
737744 where
738− f :: (Num e, Countable a, CountableDims b c, FL a b, FL c b, FL b b, FL b a, FL a a)
745+ 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)
739746 => Matrix e cols (Either a b) -> Matrix e cols (Either a (Either b c))
740747 f m = fork (tr i1) (i1 . tr i2) . m
741− g :: (Num e, CountableDims b c, FL b c, FL c c) => Matrix e a c -> Matrix e a (Either b c)
748+ g :: (Num e, CountableDimensions b c, FromLists e b c, FromLists e c c) => Matrix e a c -> Matrix e a (Either b c)
742749 g m = i2 . m
743750
744751-- McCarthy's Conditional
@@ -747,9 +754,9 @@ branch x l r = f x `select` g l `select` r
747754cond ::
748755 ( Trivial cols,
749756 Countable cols,
750− FL () cols,
751− FL cols (),
752− FL cols cols,
757+ FromLists e () cols,
758+ FromLists e cols (),
759+ FromLists e cols cols,
753760 Bounded a,
754761 Enum a,
755762 Num e,
@@ -762,9 +769,9 @@ cond p f g = join f g . grd p
762769grd ::
763770 ( Trivial q,
764771 Countable q,
765− FL () q,
766− FL q (),
767− FL q q,
772+ FromLists e () q,
773+ FromLists e q (),
774+ FromLists e q q,
768775 Bounded a,
769776 Enum a,
770777 Num e,
@@ -778,14 +785,14 @@ corr ::
778785 forall e a q .
779786 ( Trivial q,
780787 Countable q,
781− FL () q,
782− FL q (),
783− FL q q,
788+ FromLists e () q,
789+ FromLists e q (),
790+ FromLists e q q,
784791 Liftable e a Bool
785792 )
786793 => (a -> Bool) -> Matrix e q q
787794corr p = let f = fromF' p :: Matrix e q ()
788− in kr f (id :: Matrix e q q)
795+ in kr f (iden :: Matrix e q q)
789796
790797-- Pretty print
791798
@@ -809,7 +816,7 @@ prettyAux (h : t) l = "│ " ++ fill (unwords $ map show h) ++ " │\n" ++
809816 fill str = replicate (widest - length str - 2) ' ' ++ str
810817
811818-- | Matrix pretty printer
812−pretty :: (CountableDims cols rows, Show e) => Matrix e cols rows -> String
819+pretty :: (CountableDimensions cols rows, Show e) => Matrix e cols rows -> String
813820pretty m = concat
814821 [ "┌ ", unwords (replicate (columns m) blank), " ┐\n"
815822 , unlines
@@ -838,11 +845,12 @@ pretty m = concat
838845 (safeGet i j m)
839846
840847-- | Matrix pretty printer
841−prettyPrint :: (CountableDims cols rows, Show e) => Matrix e cols rows -> IO ()
848+prettyPrint :: (CountableDimensions cols rows, Show e) => Matrix e cols rows -> IO ()
842849prettyPrint = putStrLn . pretty
843850
844851-- | Zip two matrices with a given binary function
845852zipWithM :: (e -> f -> g) -> Matrix e cols rows -> Matrix f cols rows -> Matrix g cols rows
853+zipWithM _ Empty Empty = Empty
846854zipWithM f (One a) (One b) = One (f a b)
847855zipWithM f (Join a b) (Join c d) = Join (zipWithM f a c) (zipWithM f b d)
848856zipWithM f (Fork a b) (Fork c d) = Fork (zipWithM f a c) (zipWithM f b d)
@@ -867,12 +875,14 @@ fromBool False = nat 0
867875
868876-- | Relational negation
869877negateM :: Relation cols rows -> Relation cols rows
878+negateM Empty = Empty
870879negateM (One (Nat p)) = One (Nat (negate p))
871880negateM (Join a b) = Join (negateM a) (negateM b)
872881negateM (Fork a b) = Fork (negateM a) (negateM b)
873882
874883-- | Relational addition
875884orM :: Relation cols rows -> Relation cols rows -> Relation cols rows
885+orM Empty Empty = Empty
876886orM (One a) (One b) = One (fromBool (toBool a || toBool b))
877887orM (Join a b) (Join c d) = Join (orM a c) (orM b d)
878888orM (Fork a b) (Fork c d) = Fork (orM a c) (orM b d)
@@ -881,6 +891,7 @@ orM x@(Join _ _) y@(Fork _ _) = orM (abideJF x) y
881891
882892-- | Relational multiplication
883893andM :: Relation cols rows -> Relation cols rows -> Relation cols rows
894+andM Empty Empty = Empty
884895andM (One a) (One b) = One (fromBool (toBool a && toBool b))
885896andM (Join a b) (Join c d) = Join (andM a c) (andM b d)
886897andM (Fork a b) (Fork c d) = Fork (andM a c) (andM b d)
@@ -889,6 +900,7 @@ andM x@(Join _ _) y@(Fork _ _) = andM (abideJF x) y
889900
890901-- | Relational subtraction
891902subM :: Relation cols rows -> Relation cols rows -> Relation cols rows
903+subM Empty Empty = Empty
892904subM (One a) (One b) = if a - b < nat 0 then One (nat 0) else One (a - b)
893905subM (Join a b) (Join c d) = Join (subM a c) (subM b d)
894906subM (Fork a b) (Fork c d) = Fork (subM a c) (subM b d)
@@ -897,6 +909,7 @@ subM x@(Join _ _) y@(Fork _ _) = subM (abideJF x) y
897909
898910-- | Matrix relational composition.
899911compRel :: Relation cr rows -> Relation cols cr -> Relation cols rows
912+compRel Empty Empty = Empty
900913compRel (One a) (One b) = One (fromBool (toBool a && toBool b))
901914compRel (Join a b) (Fork c d) = orM (compRel a c) (compRel b d) -- Divide-and-conquer law
902915compRel (Fork a b) c = Fork (compRel a c) (compRel b c) -- Fork fusion law
@@ -904,6 +917,7 @@ compRel c (Join a b) = Join (compRel c a) (compRel c b) -- Join fusion
904917
905918-- | Matrix relational right division
906919divR :: Relation b c -> Relation b a -> Relation a c
920+divR Empty Empty = Empty
907921divR (One a) (One b) = One (fromBool (not (toBool b) || toBool a)) -- b implies a
908922divR (Join a b) (Join c d) = andM (divR a c) (divR b d)
909923divR (Fork a b) c = Fork (divR a c) (divR b c)
@@ -926,24 +940,58 @@ divS s r = divL r s `intersection` divR (tr r) (tr s)
926940fromFRel' ::
927941 forall a b cols rows.
928942 ( Liftable Boolean a b,
929− CountableDims cols rows,
930− FL rows cols
943+ CountableDimensions cols rows,
944+ FromLists Boolean rows cols
931945 ) =>
932946 (a -> b) ->
933947 Relation cols rows
934−fromFRel' = fromF'
948+fromFRel' f =
949+ let minA = minBound @a
950+ maxA = maxBound @a
951+ minB = minBound @b
952+ maxB = maxBound @b
953+ ccols = fromInteger $ natVal (Proxy :: Proxy (Count cols))
954+ rrows = fromInteger $ natVal (Proxy :: Proxy (Count rows))
955+ elementsA = take ccols [minA .. maxA]
956+ elementsB = take rrows [minB .. maxB]
957+ combinations = (,) <$> elementsA <*> elementsB
958+ combAp = map snd . sort . map (\(a, b) -> if f a == b
959+ then ((fromEnum a, fromEnum b), nat 1)
960+ else ((fromEnum a, fromEnum b), nat 0)) $ combinations
961+ mList = buildList combAp rrows
962+ in tr $ fromLists mList
963+ where
964+ buildList [] _ = []
965+ buildList l r = take r l : buildList (drop r l) r
935966
936967-- | Lifts functions to relations with dimensions matching @a@ and @b@
937968-- cardinality's.
938969fromFRel ::
939970 forall a b.
940971 ( Liftable Boolean a b,
941− CountableDimsN a b,
942− FLN b a
972+ CountableDimensionsN a b,
973+ FromLists Boolean (Normalize b) (Normalize a)
943974 ) =>
944975 (a -> b) ->
945976 Relation (Normalize a) (Normalize b)
946−fromFRel = fromFRel'
977+fromFRel f =
978+ let minA = minBound @a
979+ maxA = maxBound @a
980+ minB = minBound @b
981+ maxB = maxBound @b
982+ ccols = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize a)))
983+ rrows = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize b)))
984+ elementsA = take ccols [minA .. maxA]
985+ elementsB = take rrows [minB .. maxB]
986+ combinations = (,) <$> elementsA <*> elementsB
987+ combAp = map snd . sort . map (\(a, b) -> if f a == b
988+ then ((fromEnum a, fromEnum b), nat 1)
989+ else ((fromEnum a, fromEnum b), nat 0)) $ combinations
990+ mList = buildList combAp rrows
991+ in tr $ fromLists mList
992+ where
993+ buildList [] _ = []
994+ buildList l r = take r l : buildList (drop r l) r
947995
948996-- | Lifts a relation function to a Boolean Matrix
949997toRel ::
@@ -953,17 +1001,17 @@ toRel ::
9531001 Enum a,
9541002 Enum b,
9551003 Eq b,
956− CountableDims a b,
957− FLN b a
958− )
1004+ CountableDimensionsN a b,
1005+ FromListsN Boolean b a
1006+ )
9591007 => (a -> b -> Bool) -> Relation (Normalize a) (Normalize b)
9601008toRel f =
9611009 let minA = minBound @a
9621010 maxA = maxBound @a
9631011 minB = minBound @b
9641012 maxB = maxBound @b
965− ccols = fromInteger $ natVal (Proxy :: Proxy (Count a))
966− rrows = fromInteger $ natVal (Proxy :: Proxy (Count b))
1013+ ccols = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize a)))
1014+ rrows = fromInteger $ natVal (Proxy :: Proxy (Count (Normalize b)))
9671015 elementsA = take ccols [minA .. maxA]
9681016 elementsB = take rrows [minB .. maxB]
9691017 combinations = (,) <$> elementsA <*> elementsB
src/LAoP/Matrix/Nat.hs+77−63
@@ -56,17 +56,18 @@ module LAoP.Matrix.Nat
5656
5757 -- * Constraint type synonyms
5858 Countable,
59− CountableDims,
59+ CountableDimensions,
6060 CountableN,
6161 CountableNz,
62− CountableDimsN,
63− FLN,
64− FLNz,
62+ CountableDimensionsN,
63+ FromListsN,
64+ FromListsNz,
6565 Liftable,
6666 TrivialE,
6767 TrivialP,
6868
6969 -- * Primitives
70+ empty,
7071 one,
7172 join,
7273 fork,
@@ -77,7 +78,7 @@ module LAoP.Matrix.Nat
7778 I.Normalize,
7879
7980 -- * Matrix construction and conversion
80− I.FL,
81+ I.FromLists,
8182 fromLists,
8283 toLists,
8384 toList,
@@ -160,25 +161,38 @@ where
160161import Data.Proxy
161162import GHC.TypeLits
162163import Control.DeepSeq
164+import qualified Control.Category as C
163165import qualified LAoP.Matrix.Internal as I
164166
165167newtype Matrix e (cols :: Nat) (rows :: Nat) = M (I.Matrix e (I.FromNat cols) (I.FromNat rows))
166168 deriving (Show, Num, Eq, Ord, NFData) via (I.Matrix e (I.FromNat cols) (I.FromNat rows))
167169
168170-- | Constraint type synonyms to keep the type signatures less convoluted
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))
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
179190
180191-- Primitives
181192
193+empty :: Matrix e 0 0
194+empty = M I.Empty
195+
182196one :: e -> Matrix e 1 1
183197one = M . I.One
184198
@@ -214,27 +228,27 @@ infixl 2 ===
214228
215229-- Construction
216230
217−fromLists :: (FLN e cols rows) => [[e]] -> Matrix e cols rows
231+fromLists :: (FromListsN e cols rows) => [[e]] -> Matrix e cols rows
218232fromLists = M . I.fromLists
219233
220234-- | Matrix builder function. Constructs a matrix provided with
221235-- a construction function that operates with indices.
222236matrixBuilder' ::
223− (FLN e cols rows, CountableN cols, CountableN rows)
237+ (FromListsN e cols rows, CountableN cols, CountableN rows)
224238 => ((Int, Int) -> e) -> Matrix e cols rows
225239matrixBuilder' = M . I.matrixBuilder'
226240
227−col :: (I.FL () (I.FromNat rows)) => [e] -> Matrix e 1 rows
241+col :: (I.FromLists e () (I.FromNat rows)) => [e] -> Matrix e 1 rows
228242col = M . I.col
229243
230−row :: (I.FL (I.FromNat cols) ()) => [e] -> Matrix e cols 1
244+row :: (I.FromLists e (I.FromNat cols) ()) => [e] -> Matrix e cols 1
231245row = M . I.row
232246
233247fromF' ::
234248 ( Liftable e a b,
235249 CountableN cols,
236250 CountableN rows,
237− FLN e rows cols
251+ FromListsN e rows cols
238252 ) =>
239253 (a -> b) ->
240254 Matrix e cols rows
@@ -244,7 +258,7 @@ fromF ::
244258 ( Liftable e a b,
245259 CountableNz a,
246260 CountableNz b,
247− FLNz e b a
261+ FromListsNz e b a
248262 ) =>
249263 (a -> b) ->
250264 Matrix e (I.Count a) (I.Count b)
@@ -261,21 +275,21 @@ toList (M m) = I.toList m
261275-- Zeros Matrix
262276
263277zeros ::
264− (Num e, FLN e cols rows, CountableN cols, CountableN rows) =>
278+ (Num e, FromListsN e cols rows, CountableN cols, CountableN rows) =>
265279 Matrix e cols rows
266280zeros = M I.zeros
267281
268282-- Ones Matrix
269283
270284ones ::
271− (Num e, FLN e cols rows, CountableN cols, CountableN rows) =>
285+ (Num e, FromListsN e cols rows, CountableN cols, CountableN rows) =>
272286 Matrix e cols rows
273287ones = M I.ones
274288
275289-- Const Matrix
276290
277291constant ::
278− (Num e, FLN e cols rows, CountableN cols, CountableN rows) =>
292+ (Num e, FromListsN e cols rows, CountableN cols, CountableN rows) =>
279293 e ->
280294 Matrix e cols rows
281295constant = M . I.constant
@@ -284,14 +298,14 @@ constant = M . I.constant
284298
285299bang ::
286300 forall e cols.
287− (Num e, Enum e, I.FL (I.FromNat cols) (), CountableN cols) =>
301+ (Num e, Enum e, I.FromLists e (I.FromNat cols) (), CountableN cols) =>
288302 Matrix e cols 1
289303bang = M I.bang
290304
291305-- iden Matrix
292306
293307iden ::
294− (Num e, FLN e cols cols, CountableN cols) =>
308+ (Num e, FromListsN e cols cols, CountableN cols) =>
295309 Matrix e cols cols
296310iden = M I.iden
297311
@@ -316,9 +330,9 @@ infixl 7 ./
316330
317331p1 ::
318332 ( Num e,
319− CountableDimsN n m,
320− FLN e n m,
321− FLN e m m,
333+ CountableDimensionsN n m,
334+ FromListsN e n m,
335+ FromListsN e m m,
322336 TrivialE m n
323337 ) =>
324338 Matrix e (m + n) m
@@ -326,9 +340,9 @@ p1 = M I.p1
326340
327341p2 ::
328342 ( Num e,
329− CountableDimsN n m,
330− FLN e m n,
331− FLN e n n,
343+ CountableDimensionsN n m,
344+ FromListsN e m n,
345+ FromListsN e n n,
332346 TrivialE m n
333347 ) =>
334348 Matrix e (m + n) n
@@ -338,9 +352,9 @@ p2 = M I.p2
338352
339353i1 ::
340354 ( Num e,
341− CountableDimsN n rows,
342− FLN e n rows,
343− FLN e rows rows,
355+ CountableDimensionsN n rows,
356+ FromListsN e n rows,
357+ FromListsN e rows rows,
344358 TrivialE rows n
345359 ) =>
346360 Matrix e rows (rows + n)
@@ -348,9 +362,9 @@ i1 = tr p1
348362
349363i2 ::
350364 ( Num e,
351− CountableDimsN rows m,
352− FLN e m rows,
353− FLN e rows rows,
365+ CountableDimensionsN rows m,
366+ FromListsN e m rows,
367+ FromListsN e rows rows,
354368 TrivialE m rows
355369 ) =>
356370 Matrix e rows (m + rows)
@@ -369,11 +383,11 @@ infixl 5 -|-
369383-- | Coproduct Bifunctor (Direct sum)
370384(-|-) ::
371385 ( Num e,
372− CountableDimsN j k,
373− FLN e k k,
374− FLN e j k,
375− FLN e k j,
376− FLN e j j,
386+ CountableDimensionsN j k,
387+ FromListsN e k k,
388+ FromListsN e j k,
389+ FromListsN e k j,
390+ FromListsN e j j,
377391 TrivialE n m,
378392 TrivialE k j
379393 ) =>
@@ -386,9 +400,9 @@ infixl 5 -|-
386400fstM ::
387401 forall e m k .
388402 ( Num e,
389− CountableDimsN m k,
403+ CountableDimensionsN m k,
390404 CountableN (m * k),
391− FLN e (m * k) m,
405+ FromListsN e (m * k) m,
392406 TrivialP m k
393407 ) => Matrix e (m * k) m
394408fstM = M (I.fstM @e @(I.FromNat m) @(I.FromNat k))
@@ -397,8 +411,8 @@ fstM = M (I.fstM @e @(I.FromNat m) @(I.FromNat k))
397411sndM ::
398412 forall e m k.
399413 ( Num e,
400− CountableDimsN k m,
401− FLN e (m * k) k,
414+ CountableDimensionsN k m,
415+ FromListsN e (m * k) k,
402416 CountableN (m * k),
403417 TrivialP m k
404418 ) => Matrix e (m * k) k
@@ -408,10 +422,10 @@ sndM = M (I.sndM @e @(I.FromNat m) @(I.FromNat k))
408422kr ::
409423 forall e cols a b.
410424 ( Num e,
411− CountableDimsN a b,
425+ CountableDimensionsN a b,
412426 CountableN (a * b),
413− FLN e (a * b) a,
414− FLN e (a * b) b,
427+ FromListsN e (a * b) a,
428+ FromListsN e (a * b) b,
415429 TrivialP a b
416430 ) => Matrix e cols a -> Matrix e cols b -> Matrix e cols (a * b)
417431kr a b =
@@ -425,13 +439,13 @@ infixl 4 ><
425439(><) ::
426440 forall e m p n q.
427441 ( Num e,
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,
442+ CountableDimensionsN m n,
443+ CountableDimensionsN p q,
444+ CountableDimensionsN (m * n) (p * q),
445+ FromListsN e (m * n) m,
446+ FromListsN e (m * n) n,
447+ FromListsN e (p * q) p,
448+ FromListsN e (p * q) q,
435449 TrivialP m n,
436450 TrivialP p q
437451 ) => Matrix e m p -> Matrix e n q -> Matrix e (m * n) (p * q)
@@ -455,7 +469,7 @@ tr (M m) = M (I.tr m)
455469-- Selective 'select' operator
456470select ::
457471 ( Num e,
458− FLN e rows1 rows1,
472+ FromListsN e rows1 rows1,
459473 CountableN rows1,
460474 I.FromNat rows2 ~ I.FromNat rows1,
461475 I.FromNat cols1 ~ I.FromNat cols2,
@@ -468,9 +482,9 @@ select (M m) (M y) = M (I.select m y)
468482cond ::
469483 ( I.FromNat (I.Count (I.FromNat cols)) ~ I.FromNat cols,
470484 CountableN cols,
471− I.FL () (I.FromNat cols),
472− I.FL (I.FromNat cols) (),
473− FLN e cols cols,
485+ I.FromLists e () (I.FromNat cols),
486+ I.FromLists e (I.FromNat cols) (),
487+ FromListsN e cols cols,
474488 Liftable e a Bool
475489 )
476490 =>
@@ -479,10 +493,10 @@ cond p (M a) (M b) = M (I.cond p a b)
479493
480494-- Pretty print
481495
482−pretty :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> String
496+pretty :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> String
483497pretty (M m) = I.pretty m
484498
485−prettyPrint :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> IO ()
499+prettyPrint :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> IO ()
486500prettyPrint (M m) = I.prettyPrint m
487501
488502-- | Zip two matrices with a given binary function
src/LAoP/Matrix/Type.hs+123−128
@@ -1,11 +1,11 @@
11{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE TypeFamilies #-}
32{-# LANGUAGE AllowAmbiguousTypes #-}
43{-# LANGUAGE DataKinds #-}
54{-# LANGUAGE DerivingVia #-}
65{-# LANGUAGE FlexibleContexts #-}
76{-# LANGUAGE FlexibleInstances #-}
87{-# 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− CountableDims,
61+ CountableDimensions,
6262 CountableN,
63− CountableDimsN,
64− FLN,
63+ CountableDimensionsN,
64+ FromListsN,
6565 Liftable,
6666 Trivial,
6767 TrivialP,
@@ -71,6 +71,7 @@ module LAoP.Matrix.Type
7171 One,
7272
7373 -- * Primitives
74+ empty,
7475 one,
7576 join,
7677 fork,
@@ -104,8 +105,8 @@ module LAoP.Matrix.Type
104105 multM,
105106
106107 -- * Selective equivalent instance function
107− selectM,
108−
108+ selectM,
109+
109110 -- * Monad equivalent instance function
110111 returnM,
111112 bindM,
@@ -113,9 +114,7 @@ module LAoP.Matrix.Type
113114 -- * Misc
114115 -- ** Get dimensions
115116 columns,
116− columns',
117117 rows,
118− rows',
119118
120119 -- ** Matrix Transposition
121120 tr,
@@ -183,44 +182,46 @@ where
183182import Data.Void
184183import Data.Proxy
185184import Data.Kind
186−import GHC.TypeLits
185+import GHC.TypeLits
187186import Control.DeepSeq
188187import LAoP.Utils
188+import qualified Control.Category as C
189189import qualified LAoP.Matrix.Internal as I
190−import Prelude hiding (id, (.))
191190
192191newtype Matrix e (cols :: Type) (rows :: Type) = M (I.Matrix e (I.Normalize cols) (I.Normalize rows))
193192 deriving (Show, Num, Eq, Ord, NFData) via (I.Matrix e (I.Normalize cols) (I.Normalize rows))
194193
195194-- | Constraint type synonyms to keep the type signatures less convoluted
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
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 e a b = I.FromLists e (I.Normalize a) (I.Normalize b)
200+type Liftable e a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num e, Ord e)
201+type Trivial a = I.Normalize (I.Normalize a) ~ I.Normalize (I.Normalize (I.Normalize a))
202+type Trivial2 a = I.Normalize a ~ I.Normalize (I.Normalize a)
203+type Trivial3 a = I.FromNat (I.Count (I.Normalize (I.Normalize a))) ~ I.Normalize (I.Normalize a)
204+type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
205+
206+-- | It isn't possible to implement the 'id' function so it's
207+-- implementation is 'undefined'. However 'comp' can be and this partial
208+-- class implementation exists just to make the code more readable.
209+--
210+-- Please use 'iden' instead.
211+instance (Num e) => C.Category (Matrix e) where
212+ id = undefined
213+ (.) = comp
213214
214215-- | Bifunctor equivalent function
215216bimapM ::
216217 ( Liftable e a b,
217218 Liftable e c d,
218− CountableDimsN a c,
219− CountableDimsN b d,
220− FLN d c,
221− FLN b a
219+ CountableDimensionsN a c,
220+ CountableDimensionsN b d,
221+ FromListsN e d c,
222+ FromListsN e b a
222223 ) => (a -> b) -> (c -> d) -> Matrix e a c -> Matrix e b d
223−bimapM f g m = fromF g . m . tr (fromF f)
224+bimapM f g m = fromF g `comp` m `comp` tr (fromF f)
224225
225226-- | Zero type alias
226227type Zero = Void
@@ -230,6 +231,10 @@ type One = ()
230231
231232-- Primitives
232233
234+-- | Empty matrix constructor
235+empty :: Matrix e Zero Zero
236+empty = M I.Empty
237+
233238-- | Unit matrix constructor
234239one :: e -> Matrix e One One
235240one = M . I.One
@@ -267,37 +272,37 @@ infixl 2 ===
267272-- Functor hierarchy
268273
269274-- | Functor instance equivalent function
270−fmapM ::
275+fmapM ::
271276 ( Liftable e a b,
272− CountableDimsN a b,
273− FLN b a
277+ CountableDimensionsN a b,
278+ FromListsN e b a
274279 )
275280 =>
276281 (a -> b) -> Matrix e c a -> Matrix e c b
277−fmapM f m = fromF f . m
282+fmapM f m = fromF f `comp` m
278283
279284-- | Applicative instance equivalent 'unit' function,
280285unitM :: (Num e) => Matrix e () ()
281286unitM = one 1
282287
283288-- | Applicative instance equivalent 'unit' function,
284−multM ::
285− ( CountableDimsN a b,
289+multM ::
290+ ( CountableDimensionsN a b,
286291 CountableN (a, b),
287292 Num e,
288− FLN (a, b) a,
289− FLN (a, b) b,
293+ FromListsN e (a, b) a,
294+ FromListsN e (a, b) b,
290295 TrivialP a b
291296 ) => Matrix e c a -> Matrix e c b -> Matrix e c (a, b)
292297multM = kr
293298
294299-- | Monad instance equivalent 'return' function,
295−returnM ::
296− forall e a .
300+returnM ::
301+ forall e a .
297302 ( Num e,
298303 Enum e,
299304 Enum a,
300− FLN () a,
305+ FromListsN e () a,
301306 Countable a
302307 ) => a -> Matrix e One a
303308returnM a = col l
@@ -314,35 +319,35 @@ bindM = flip comp
314319
315320-- | Build a matrix out of a list of list of elements. Throws a runtime
316321-- error if the dimensions do not match.
317−fromLists :: (FLN cols rows) => [[e]] -> Matrix e cols rows
322+fromLists :: (FromListsN e cols rows) => [[e]] -> Matrix e cols rows
318323fromLists = M . I.fromLists
319324
320325-- | Matrix builder function. Constructs a matrix provided with
321326-- a construction function that operates with indices.
322327matrixBuilder' ::
323− (FLN cols rows, CountableDimsN cols rows )
328+ (FromListsN e cols rows, CountableDimensionsN cols rows )
324329 => ((Int, Int) -> e) -> Matrix e cols rows
325330matrixBuilder' = M . I.matrixBuilder'
326331
327332-- | Matrix builder function. Constructs a matrix provided with
328333-- a construction function that operates with arbitrary types.
329334matrixBuilder ::
330− ( FLN a b,
335+ ( FromListsN e a b,
331336 Enum a,
332337 Enum b,
333338 Bounded a,
334339 Bounded b,
335340 Eq a,
336− Countable b
341+ CountableDimensionsN a b
337342 ) => ((a, b) -> e) -> Matrix e a b
338343matrixBuilder f = M (I.matrixBuilder f)
339344
340345-- | Constructs a column vector matrix
341−col :: (FLN () rows) => [e] -> Matrix e One rows
346+col :: (FromListsN e () rows) => [e] -> Matrix e One rows
342347col = M . I.col
343348
344349-- | Constructs a row vector matrix
345−row :: (FLN cols ()) => [e] -> Matrix e cols One
350+row :: (FromListsN e cols ()) => [e] -> Matrix e cols One
346351row = M . I.row
347352
348353-- | Lifts functions to matrices with arbitrary dimensions.
@@ -351,8 +356,8 @@ row = M . I.row
351356-- types @a@ or @b@ allows.
352357fromF' ::
353358 ( Liftable e a b,
354− CountableDimsN cols rows,
355− FLN rows cols
359+ CountableDimensionsN cols rows,
360+ FromListsN e rows cols
356361 ) =>
357362 (a -> b) -> Matrix e cols rows
358363fromF' = M . I.fromF'
@@ -361,8 +366,8 @@ fromF' = M . I.fromF'
361366-- cardinality's.
362367fromF ::
363368 ( Liftable e a b,
364− CountableDimsN a b,
365− FLN b a
369+ CountableDimensionsN a b,
370+ FromListsN e b a
366371 ) =>
367372 (a -> b) -> Matrix e a b
368373fromF = M . I.fromF
@@ -370,8 +375,8 @@ fromF = M . I.fromF
370375-- | Lifts relation functions to Boolean Matrix
371376toRel ::
372377 ( Liftable (Natural 0 1) a b,
373− CountableDims a b,
374− FLN b a
378+ CountableDimensionsN a b,
379+ FromListsN (Natural 0 1) b a
375380 ) => (a -> b -> Bool) -> Matrix (Natural 0 1) a b
376381toRel = M . I.toRel
377382
@@ -389,7 +394,7 @@ toList (M m) = I.toList m
389394
390395-- | The zero matrix. A matrix wholly filled with zeros.
391396zeros ::
392− (Num e, FLN cols rows, CountableDimsN cols rows)
397+ (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
393398 => Matrix e cols rows
394399zeros = M I.zeros
395400
@@ -399,7 +404,7 @@ zeros = M I.zeros
399404--
400405-- Also known as T (Top) matrix.
401406ones ::
402− (Num e, FLN cols rows, CountableDimsN cols rows)
407+ (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
403408 => Matrix e cols rows
404409ones = M I.ones
405410
@@ -408,7 +413,7 @@ ones = M I.ones
408413-- | The constant matrix constructor. A matrix wholly filled with a given
409414-- value.
410415constant ::
411− (Num e, FLN cols rows, CountableDimsN cols rows)
416+ (Num e, FromListsN e cols rows, CountableDimensionsN cols rows)
412417 => e -> Matrix e cols rows
413418constant = M . I.constant
414419
@@ -417,19 +422,19 @@ constant = M . I.constant
417422-- | The T (Top) row vector matrix.
418423bang ::
419424 forall e cols.
420− (Num e, Enum e, FLN cols (), CountableN cols) =>
425+ (Num e, Enum e, FromListsN e cols (), CountableN cols) =>
421426 Matrix e cols One
422427bang = M I.bang
423428
424429-- | Point constant relation
425−point ::
430+point ::
426431 ( Bounded a,
427432 Enum a,
428433 Eq a,
429434 Num e,
430435 Ord e,
431436 CountableN a,
432− FLN a One
437+ FromListsN e a One
433438 ) => a -> Matrix e One a
434439point = fromF . const
435440
@@ -437,7 +442,7 @@ point = fromF . const
437442
438443-- | iden matrix
439444iden ::
440− (Num e, FLN a a, CountableN a) =>
445+ (Num e, FromListsN e a a, CountableN a) =>
441446 Matrix e a a
442447iden = M I.iden
443448{-# NOINLINE iden #-}
@@ -451,7 +456,7 @@ iden = M I.iden
451456comp :: (Num e) => Matrix e cr rows -> Matrix e cols cr -> Matrix e cols rows
452457comp (M a) (M b) = M (I.comp a b)
453458{-# NOINLINE comp #-}
454−{-# RULES
459+{-# RULES
455460 "comp/iden1" forall m. comp m iden = m ;
456461 "comp/iden2" forall m. comp iden m = m
457462#-}
@@ -473,9 +478,9 @@ infixl 7 ./
473478-- | Biproduct first component projection
474479p1 ::
475480 ( Num e,
476− CountableDimsN n m,
477− FLN n m,
478− FLN m m
481+ CountableDimensionsN n m,
482+ FromListsN e n m,
483+ FromListsN e m m
479484 ) =>
480485 Matrix e (Either m n) m
481486p1 = M I.p1
@@ -483,9 +488,9 @@ p1 = M I.p1
483488-- | Biproduct second component projection
484489p2 ::
485490 ( Num e,
486− CountableDimsN n m,
487− FLN m n,
488− FLN n n
491+ CountableDimensionsN n m,
492+ FromListsN e m n,
493+ FromListsN e n n
489494 ) =>
490495 Matrix e (Either m n) n
491496p2 = M I.p2
@@ -495,9 +500,9 @@ p2 = M I.p2
495500-- | Biproduct first component injection
496501i1 ::
497502 ( Num e,
498− CountableDimsN n m,
499− FLN n m,
500− FLN m m
503+ CountableDimensionsN n m,
504+ FromListsN e n m,
505+ FromListsN e m m
501506 ) =>
502507 Matrix e m (Either m n)
503508i1 = tr p1
@@ -505,9 +510,9 @@ i1 = tr p1
505510-- | Biproduct second component injection
506511i2 ::
507512 ( Num e,
508− CountableDimsN n m,
509− FLN m n,
510− FLN n n
513+ CountableDimensionsN n m,
514+ FromListsN e m n,
515+ FromListsN e n n
511516 ) =>
512517 Matrix e n (Either m n)
513518i2 = tr p2
@@ -516,34 +521,24 @@ i2 = tr p2
516521
517522-- | Obtain the number of rows.
518523--
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''.
524+-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
525+-- dimensions in constant time.
526+--
527+-- TODO: A 'rows' function that does not need the 'KnownNat' constraint in
528+-- exchange for performance.
522529rows :: (CountableN rows) => Matrix e cols rows -> Int
523530rows (M m) = I.rows m
524531
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−
532532-- | Obtain the number of columns.
533+--
534+-- NOTE: The 'KnownNat' constaint is needed in order to obtain the
535+-- dimensions in constant time.
533536--
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''.
537+-- TODO: A 'columns' function that does not need the 'KnownNat' constraint in
538+-- exchange for performance.
537539columns :: (CountableN cols) => Matrix e cols rows -> Int
538540columns (M m) = I.columns m
539541
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−
547542-- Coproduct Bifunctor
548543
549544infixl 5 -|-
@@ -551,11 +546,11 @@ infixl 5 -|-
551546-- | Matrix coproduct functor also known as matrix direct sum.
552547(-|-) ::
553548 ( Num e,
554− CountableDimsN j k,
555− FLN k k,
556− FLN j k,
557− FLN k j,
558− FLN j j
549+ CountableDimensionsN j k,
550+ FromListsN e k k,
551+ FromListsN e j k,
552+ FromListsN e k j,
553+ FromListsN e j j
559554 ) =>
560555 Matrix e n k ->
561556 Matrix e m j ->
@@ -565,23 +560,23 @@ infixl 5 -|-
565560-- Khatri Rao Product and projections
566561
567562-- | Khatri Rao product first component projection matrix.
568−fstM ::
563+fstM ::
569564 forall e m k .
570565 ( Num e,
571− CountableDimsN m k,
566+ CountableDimensionsN m k,
572567 CountableN (m, k),
573− FLN (m, k) m,
568+ FromListsN e (m, k) m,
574569 TrivialP m k
575570 ) => Matrix e (m, k) m
576571fstM = M (I.fstM @e @(I.Normalize m) @(I.Normalize k))
577572
578573-- | Khatri Rao product second component projection matrix.
579−sndM ::
574+sndM ::
580575 forall e m k.
581576 ( Num e,
582− CountableDimsN k m,
577+ CountableDimensionsN k m,
583578 CountableN (m, k),
584− FLN (m, k) k,
579+ FromListsN e (m, k) k,
585580 TrivialP m k
586581 ) => Matrix e (m, k) k
587582sndM = M (I.sndM @e @(I.Normalize m) @(I.Normalize k))
@@ -589,21 +584,21 @@ sndM = M (I.sndM @e @(I.Normalize m) @(I.Normalize k))
589584-- | Khatri Rao Matrix product also known as matrix pairing.
590585--
591586-- NOTE: That this is not a true categorical product, see for instance:
592−--
587+--
593588-- @
594−-- | fstM . kr a b == a
589+-- | fstM `comp` kr a b == a
595590-- kr a b ==> |
596−-- | sndM . kr a b == b
591+-- | sndM `comp` kr a b == b
597592-- @
598593--
599594-- __Emphasis__ on the implication symbol.
600595kr ::
601596 forall e cols a b.
602597 ( Num e,
603− CountableDimsN a b,
598+ CountableDimensionsN a b,
604599 CountableN (a, b),
605− FLN (a, b) a,
606− FLN (a, b) b,
600+ FromListsN e (a, b) a,
601+ FromListsN e (a, b) b,
607602 TrivialP a b
608603 ) => Matrix e cols a -> Matrix e cols b -> Matrix e cols (a, b)
609604kr a b =
@@ -619,13 +614,13 @@ infixl 4 ><
619614(><) ::
620615 forall e m p n q.
621616 ( Num e,
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,
617+ CountableDimensionsN m n,
618+ CountableDimensionsN p q,
619+ CountableDimensionsN (m, n) (p, q),
620+ FromListsN e (m, n) m,
621+ FromListsN e (m, n) n,
622+ FromListsN e (p, q) p,
623+ FromListsN e (p, q) q,
629624 TrivialP m n,
630625 TrivialP p q
631626 ) => Matrix e m p -> Matrix e n q -> Matrix e (m, n) (p, q)
@@ -637,7 +632,7 @@ infixl 4 ><
637632-- Matrix abide Join Fork
638633
639634-- | Matrix "abiding" followin the 'Join'-'Fork' abide law.
640−--
635+--
641636-- Law:
642637--
643638-- @
@@ -649,7 +644,7 @@ abideJF (M m) = M (I.abideJF m)
649644-- Matrix abide Fork Join
650645
651646-- | Matrix "abiding" followin the 'Fork'-'Join' abide law.
652−--
647+--
653648-- Law:
654649--
655650-- @
@@ -668,9 +663,9 @@ tr (M m) = M (I.tr m)
668663
669664-- | Selective functors 'select' operator equivalent inspired by the
670665-- ArrowMonad solution presented in the paper.
671−selectM ::
666+selectM ::
672667 ( Num e,
673− FLN b b,
668+ FromListsN e b b,
674669 CountableN b
675670 ) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
676671selectM (M m) (M y) = M (I.select m y)
@@ -683,9 +678,9 @@ cond ::
683678 Trivial2 a,
684679 Trivial3 a,
685680 CountableN a,
686− FLN () a,
687− FLN a (),
688− FLN a a,
681+ FromListsN e () a,
682+ FromListsN e a (),
683+ FromListsN e a a,
689684 Liftable e a Bool
690685 )
691686 =>
@@ -695,11 +690,11 @@ cond p (M a) (M b) = M (I.cond p a b)
695690-- Pretty print
696691
697692-- | Matrix pretty printer
698−pretty :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> String
693+pretty :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> String
699694pretty (M m) = I.pretty m
700695
701696-- | Matrix pretty printer
702−prettyPrint :: (CountableDimsN cols rows, Show e) => Matrix e cols rows -> IO ()
697+prettyPrint :: (CountableDimensionsN cols rows, Show e) => Matrix e cols rows -> IO ()
703698prettyPrint (M m) = I.prettyPrint m
704699
705700-- | Zip two matrices with a given binary function
src/LAoP/Relation.hs+4−3
@@ -32,15 +32,16 @@ module LAoP.Relation
3232
3333 -- * Constraint type synonyms
3434 Countable,
35− CountableDims,
35+ CountableDimensions,
3636 CountableN,
37− CountableDimsN,
38− FLN,
37+ CountableDimensionsN,
38+ FromListsN,
3939 Liftable,
4040 Trivial,
4141 TrivialP,
4242
4343 -- * Primitives
44+ empty,
4445 one,
4546 join,
4647 (|||),
src/LAoP/Relation/Internal.hs+196−193
@@ -1,4 +1,3 @@
1−{-# LANGUAGE TypeFamilies #-}
21{-# LANGUAGE ConstraintKinds #-}
32{-# LANGUAGE GADTs #-}
43{-# LANGUAGE UndecidableInstances #-}
@@ -43,15 +42,16 @@ module LAoP.Relation.Internal
4342
4443 -- * Constraint type synonyms
4544 Countable,
46− CountableDims,
45+ CountableDimensions,
4746 CountableN,
48− CountableDimsN,
49− FLN,
47+ CountableDimensionsN,
48+ FromListsN,
5049 Liftable,
5150 Trivial,
5251 TrivialP,
5352
5453 -- * Primitives
54+ empty,
5555 one,
5656 join,
5757 (|||),
@@ -178,9 +178,9 @@ import Data.Void
178178import qualified LAoP.Matrix.Internal as I
179179import LAoP.Utils.Internal
180180import Control.DeepSeq
181+import qualified Control.Category as C
181182import Data.Bool
182183import GHC.TypeLits
183−import Prelude hiding (id, (.))
184184
185185-- | Boolean type synonym for working with boolean matrices
186186type Boolean = Natural 0 1
@@ -193,21 +193,23 @@ newtype Relation a b = R (I.Matrix Boolean (I.Normalize a) (I.Normalize b))
193193deriving instance (Read (I.Matrix Boolean (I.Normalize a) (I.Normalize b))) => Read (Relation a b)
194194
195195-- | Constraint type synonyms to keep the type signatures less convoluted
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
196+type Countable a = KnownNat (I.Count a)
197+type CountableDimensions a b = (Countable a, Countable b)
198+type CountableN a = KnownNat (I.Count (I.Normalize a))
199+type CountableDimensionsN a b = (CountableN a, CountableN b)
200+type FromListsN a b = I.FromLists Boolean (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 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 C.Category Relation where
211+ id = undefined
212+ (.) = comp
211213
212214instance Num (Relation a b) where
213215 -- | Matrix addition becomes Boolean matrix disjointion
@@ -228,6 +230,10 @@ type One = ()
228230
229231-- Primitives
230232
233+-- | Empty matrix constructor
234+empty :: Relation Zero Zero
235+empty = R I.Empty
236+
231237-- | Unit matrix constructor
232238one :: Boolean -> Relation One One
233239one = R . I.One
@@ -264,26 +270,26 @@ infixl 2 ===
264270
265271-- | Build a matrix out of a list of list of elements. Throws a runtime
266272-- error if the dimensions do not match.
267−fromLists :: (FLN a b) => [[Boolean]] -> Relation a b
273+fromLists :: (FromListsN a b) => [[Boolean]] -> Relation a b
268274fromLists = R . I.fromLists
269275
270276-- | Relation builder function. Constructs a relation provided with
271277-- a construction function that operates with indices.
272278relationBuilder' ::
273− (FLN a b, CountableDimsN a b) =>
279+ (FromListsN a b, CountableDimensionsN a b) =>
274280 ((Int, Int) -> Boolean) -> Relation a b
275281relationBuilder' = R . I.matrixBuilder'
276282
277283-- | Relation builder function. Constructs a relation provided with
278284-- a construction function that operates with arbitrary types.
279285relationBuilder ::
280− ( FLN a b,
286+ ( FromListsN a b,
281287 Enum a,
282288 Enum b,
283289 Bounded a,
284290 Bounded b,
285291 Eq a,
286− CountableDims a b
292+ CountableDimensionsN a b
287293 ) => ((a, b) -> Boolean) -> Relation a b
288294relationBuilder = R . I.matrixBuilder
289295
@@ -293,18 +299,18 @@ relationBuilder = R . I.matrixBuilder
293299-- types @a@ or @b@ allows.
294300fromF' ::
295301 ( Liftable a b,
296− CountableDimsN c d,
297− FLN d c
302+ CountableDimensionsN c d,
303+ FromListsN d c
298304 )
299305 => (a -> b) -> Relation c d
300306fromF' f = R (I.fromFRel' f)
301307
302308-- | Lifts functions to matrices with dimensions matching @a@ and @b@
303309-- cardinality's.
304−fromF ::
310+fromF ::
305311 ( Liftable a b,
306− CountableDimsN a b,
307− FLN b a
312+ CountableDimensionsN a b,
313+ FromListsN b a
308314 )
309315 => (a -> b) -> Relation a b
310316fromF f = R (I.fromFRel f)
@@ -312,8 +318,8 @@ fromF f = R (I.fromFRel f)
312318-- | Lifts relation functions to 'Relation'
313319toRel ::
314320 ( Liftable a b,
315− CountableDims a b,
316− FLN b a
321+ CountableDimensionsN a b,
322+ FromListsN b a
317323 )
318324 => (a -> b -> Bool) -> Relation a b
319325toRel = R . I.toRel
@@ -322,9 +328,9 @@ toRel = R . I.toRel
322328fromRel ::
323329 ( Liftable a b,
324330 Eq a,
325− CountableDimsN a b,
326− FLN a One,
327− FLN b One
331+ CountableDimensionsN a b,
332+ FromListsN a One,
333+ FromListsN b One
328334 )
329335 => Relation a b -> (a -> b -> Bool)
330336fromRel r a b = pointApBool a b r
@@ -348,12 +354,12 @@ toBool r = case toList r of
348354-- | Power transpose.
349355--
350356-- Maps a relation to a set valued function.
351−pt ::
357+pt ::
352358 ( Liftable a b,
353359 Eq a,
354− CountableDimsN a b,
355− FLN a One,
356− FLN b One
360+ CountableDimensionsN a b,
361+ FromListsN a One,
362+ FromListsN b One
357363 )
358364 => Relation a b -> (a -> List b)
359365pt r a =
@@ -365,8 +371,8 @@ belongs ::
365371 ( Bounded a,
366372 Enum a,
367373 Eq a,
368− CountableDims (List a) a,
369− FLN a (List a)
374+ CountableDimensionsN (List a) a,
375+ FromListsN a (List a)
370376 )
371377 => Relation (List a) a
372378belongs = toRel elemR
@@ -378,14 +384,14 @@ belongs = toRel elemR
378384-- | The zero relation. A relation where no element of type @a@ relates
379385-- with elements of type @b@.
380386--
381−-- Also known as ⊥ (Bottom) Relation.
387+-- Also known as ⊥ (Bottom) Relation or empty Relation.
382388--
383389-- @
384−-- r `.` ⊥ == ⊥ `.` r == ⊥
390+-- r ``comp`` ⊥ == ⊥ ``comp`` r == ⊥
385391-- ⊥ ``sse`` R && R ``sse`` T == True
386392-- @
387393zeros ::
388− (FLN a b, CountableDimsN a b) =>
394+ (FromListsN a b, CountableDimensionsN a b) =>
389395 Relation a b
390396zeros = relationBuilder' (const (nat 0))
391397
@@ -400,7 +406,7 @@ zeros = relationBuilder' (const (nat 0))
400406-- ⊥ ``sse`` R && R ``sse`` T == True
401407-- @
402408ones ::
403− (FLN a b, CountableDimsN a b) =>
409+ (FromListsN a b, CountableDimensionsN a b) =>
404410 Relation a b
405411ones = relationBuilder' (const (nat 1))
406412
@@ -408,17 +414,17 @@ ones = relationBuilder' (const (nat 1))
408414
409415-- | The T (Top) row vector relation.
410416bang ::
411− (FLN a One, CountableN a) =>
417+ (FromListsN a One, CountableN a) =>
412418 Relation a One
413419bang = ones
414420
415421-- | Point constant relation
416−point ::
422+point ::
417423 ( Bounded a,
418424 Enum a,
419425 Eq a,
420426 CountableN a,
421− FLN a One
427+ FromListsN a One
422428 ) => a -> Relation One a
423429point = fromF . const
424430
@@ -427,16 +433,16 @@ point = fromF . const
427433-- | iden matrix
428434--
429435-- @
430−-- 'iden' `.` r == r == r `.` 'iden'
436+-- 'iden' ``comp`` r == r == r ``comp`` 'iden'
431437-- @
432438iden ::
433− (FLN a a, CountableN a) => Relation a a
439+ (FromListsN a a, CountableN a) => Relation a a
434440iden = relationBuilder' (bool (nat 0) (nat 1) . uncurry (==))
435441
436442-- | Relational composition
437443--
438444-- @
439−-- r `.` (s `.` p) = (r `.` s) `.` p
445+-- r ``comp`` (s ``comp`` p) = (r ``comp`` s) ``comp`` p
440446-- @
441447comp :: Relation b c -> Relation a b -> Relation a c
442448comp (R a) (R b) = R (I.compRel a b)
@@ -484,7 +490,7 @@ shrunkBy r s = r `intersection` divR s (conv r)
484490-- r ``overriddenBy`` r == r
485491-- @
486492overriddenBy ::
487− ( FLN b b,
493+ ( FromListsN b b,
488494 CountableN b
489495 ) => Relation a b -> Relation a b -> Relation a b
490496overriddenBy r s = s `union` r `intersection` divR zeros (conv s)
@@ -496,11 +502,11 @@ overriddenBy r s = s `union` r `intersection` divR zeros (conv s)
496502pointAp ::
497503 ( Liftable a b,
498504 Eq a,
499− CountableDimsN a b,
500− FLN a One,
501− FLN b One
505+ CountableDimensionsN a b,
506+ FromListsN a One,
507+ FromListsN b One
502508 ) => a -> b -> Relation a b -> Relation One One
503−pointAp a b r = conv (point b) . r . point a
509+pointAp a b r = conv (point b) `comp` r `comp` point a
504510
505511-- | Relational application
506512--
@@ -508,11 +514,11 @@ pointAp a b r = conv (point b) . r . point a
508514pointApBool ::
509515 ( Liftable a b,
510516 Eq a,
511− CountableDimsN a b,
512− FLN a One,
513− FLN b One
517+ CountableDimensionsN a b,
518+ FromListsN a One,
519+ FromListsN b One
514520 ) => a -> b -> Relation a b -> Bool
515−pointApBool a b r = toBool $ conv (point b) . r . point a
521+pointApBool a b r = toBool $ conv (point b) `comp` r `comp` point a
516522
517523-- | Relational converse
518524--
@@ -554,8 +560,8 @@ intersection a b = a * b
554560-- @
555561-- (r ``union`` s) ``union`` t == r `'union' (s ``union`` t)
556562-- r ``union`` s ``sse`` x == r ``sse`` x && s ``sse`` x
557−-- r `.` (s ``union`` t) == (r `.` s) ``union`` (r `.` t)
558−-- (s ``union`` t) `.` r == (s `.` r) ``union`` (t `.` r)
563+-- r ``comp`` (s ``union`` t) == (r ``comp`` s) ``union`` (r ``comp`` t)
564+-- (s ``union`` t) ``comp`` r == (s ``comp`` r) ``union`` (t ``comp`` r)
559565-- @
560566union :: Relation a b -> Relation a b -> Relation a b
561567union a b = a + b
@@ -563,46 +569,46 @@ union a b = a + b
563569-- | Relation Kernel
564570--
565571-- @
566−-- 'ker' r == 'conv' r `.` r
572+-- 'ker' r == 'conv' r ``comp`` r
567573-- 'ker' r == 'img' ('conv' r)
568574-- @
569575ker :: Relation a b -> Relation a a
570−ker r = conv r . r
576+ker r = conv r `comp` r
571577
572578-- | Relation Image
573579--
574580-- @
575−-- 'img' r == r `.` conv r
581+-- 'img' r == r ``comp`` conv r
576582-- 'img' r == 'ker' ('conv' r)
577583-- @
578584img :: Relation a b -> Relation b b
579−img r = r . conv r
585+img r = r `comp` conv r
580586
581587-- | Function division. Special case of 'divS'.
582588--
583589-- NOTE: _This is only valid_ if @f@ and @g@ are 'function's, i.e. 'simple' and
584590-- 'entire'.
585591--
586−-- @'divisionF' f g == 'conv' g `.` f@
592+-- @'divisionF' f g == 'conv' g ``comp`` f@
587593divisionF :: Relation a c -> Relation b c -> Relation a b
588−divisionF f g = conv g . f
594+divisionF f g = conv g `comp` f
589595
590596-- Taxonomy of binary relations
591597
592598-- | A 'Relation' @r@ is 'simple' 'iff' @'coreflexive' ('img' r)@
593−simple :: (CountableN b, FLN b b) => Relation a b -> Bool
599+simple :: (CountableN b, FromListsN b b) => Relation a b -> Bool
594600simple = coreflexive . img
595601
596602-- | A 'Relation' @r@ is 'injective' 'iff' @'coreflexive' ('ker' r)@
597−injective :: (CountableN a, FLN a a) => Relation a b -> Bool
603+injective :: (CountableN a, FromListsN a a) => Relation a b -> Bool
598604injective = coreflexive . ker
599605
600606-- | A 'Relation' @r@ is 'entire' 'iff' @'reflexive' ('ker' r)@
601−entire :: (CountableN a, FLN a a) => Relation a b -> Bool
607+entire :: (CountableN a, FromListsN a a) => Relation a b -> Bool
602608entire = reflexive . ker
603609
604610-- | A 'Relation' @r@ is 'surjective' 'iff' @'reflexive' ('img' r)@
605−surjective :: (CountableN b, FLN b b) => Relation a b -> Bool
611+surjective :: (CountableN b, FromListsN b b) => Relation a b -> Bool
606612surjective = reflexive . img
607613
608614-- | A 'Relation' @r@ is a 'function' 'iff' @'simple' r && 'entire' r@
@@ -611,13 +617,13 @@ surjective = reflexive . img
611617-- relations:
612618--
613619-- @
614−-- f `.` r ``sse`` s == r ``sse`` f `.` s
615−-- r `.` f ``sse`` s == r ``sse`` s `.` f
620+-- f ``comp`` r ``sse`` s == r ``sse`` f ``comp`` s
621+-- r ``comp`` f ``sse`` s == r ``sse`` s ``comp`` f
616622-- @
617623function ::
618− ( CountableDimsN a b,
619− FLN a a,
620− FLN b b
624+ ( CountableDimensionsN a b,
625+ FromListsN a a,
626+ FromListsN b b
621627 )
622628 => Relation a b -> Bool
623629function r = simple r && entire r
@@ -625,7 +631,7 @@ function r = simple r && entire r
625631-- | A 'Relation' @r@ is a 'representation' 'iff' @'injective' r && 'entire' r@
626632representation ::
627633 ( CountableN a,
628− FLN a a
634+ FromListsN a a
629635 )
630636 => Relation a b -> Bool
631637representation r = injective r && entire r
@@ -633,91 +639,91 @@ representation r = injective r && entire r
633639-- | A 'Relation' @r@ is an 'abstraction' 'iff' @'surjective' r && 'simple' r@
634640abstraction ::
635641 ( CountableN b,
636− FLN b b
642+ FromListsN b b
637643 )
638644 => Relation a b -> Bool
639645abstraction r = surjective r && simple r
640646
641647-- | A 'Relation' @r@ is a 'surjection' 'iff' @'function' r && 'abstraction' r@
642648surjection ::
643− ( CountableDimsN a b,
644− FLN a a,
645− FLN b b
649+ ( CountableDimensionsN a b,
650+ FromListsN a a,
651+ FromListsN b b
646652 )
647653 => Relation a b -> Bool
648654surjection r = function r && abstraction r
649655
650656-- | A 'Relation' @r@ is a 'injection' 'iff' @'function' r && 'representation' r@
651657injection ::
652− ( CountableDimsN a b,
653− FLN a a,
654− FLN b b
658+ ( CountableDimensionsN a b,
659+ FromListsN a a,
660+ FromListsN b b
655661 )
656662 => Relation a b -> Bool
657663injection r = function r && representation r
658664
659665-- | A 'Relation' @r@ is an 'bijection' 'iff' @'injection' r && 'surjection' r@
660666bijection ::
661− ( CountableDimsN a b,
662− FLN b b,
663− FLN a a
667+ ( CountableDimensionsN a b,
668+ FromListsN b b,
669+ FromListsN a a
664670 ) => Relation a b -> Bool
665671bijection r = injection r && surjection r
666672
667673-- Properties of relations
668674
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
675+-- | A 'Relation' @r@ is 'reflexive' 'iff' @'iden' ``sse`` r@
676+reflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
677+reflexive r = iden <= r
672678
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
679+-- | A 'Relation' @r@ is 'coreflexive' 'iff' @r ``sse`` 'iden'@
680+coreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
681+coreflexive r = r <= iden
676682
677−-- | A 'Relation' @r@ is 'transitive' 'iff' @(r `.` r) ``sse`` r@
683+-- | A 'Relation' @r@ is 'transitive' 'iff' @(r ``comp`` r) ``sse`` r@
678684transitive :: Relation a a -> Bool
679−transitive r = (r . r) `sse` r
685+transitive r = (r `comp` r) `sse` r
680686
681687-- | A 'Relation' @r@ is 'symmetric' 'iff' @r == 'conv' r@
682688symmetric :: Relation a a -> Bool
683689symmetric r = r == conv r
684690
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
691+-- | A 'Relation' @r@ is anti-symmetric 'iff' @(r ``intersection`` 'conv' r) ``sse`` 'iden'@
692+antiSymmetric :: (CountableN a, FromListsN a a) => Relation a a -> Bool
693+antiSymmetric r = (r `intersection` conv r) `sse` iden
688694
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
695+-- | A 'Relation' @r@ is 'irreflexive' 'iff' @(r ``intersection`` 'iden') == 'zeros'@
696+irreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
697+irreflexive r = (r `intersection` iden) == zeros
692698
693699-- | A 'Relation' @r@ is 'connected' 'iff' @(r ``union`` 'conv' r) == 'ones'@
694−connected :: (CountableN a, FLN a a) => Relation a a -> Bool
700+connected :: (CountableN a, FromListsN a a) => Relation a a -> Bool
695701connected r = (r `union` conv r) == ones
696702
697703-- | A 'Relation' @r@ is a 'preorder' 'iff' @'reflexive' r && 'transitive' r@
698−preorder :: (CountableN a, FLN a a) => Relation a a -> Bool
704+preorder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
699705preorder r = reflexive r && transitive r
700706
701707-- | A 'Relation' @r@ is a partial-order 'iff' @'antiSymmetric' r && 'preorder' r@
702−partialOrder :: (CountableN a, FLN a a) => Relation a a -> Bool
708+partialOrder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
703709partialOrder r = antiSymmetric r && preorder r
704710
705711-- | A 'Relation' @r@ is a linear-order 'iff' @'connected' r && 'partialOrder' r@
706−linearOrder :: (CountableN a, FLN a a) => Relation a a -> Bool
712+linearOrder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
707713linearOrder r = connected r && partialOrder r
708714
709715-- | A 'Relation' @r@ is an 'equivalence' 'iff' @'symmetric' r && 'preorder' r@
710−equivalence :: (CountableN a, FLN a a) => Relation a a -> Bool
716+equivalence :: (CountableN a, FromListsN a a) => Relation a a -> Bool
711717equivalence r = symmetric r && preorder r
712718
713719-- | A 'Relation' @r@ is a partial-equivalence 'iff' @'partialOrder' r && 'equivalence' r@
714−partialEquivalence :: (CountableN a, FLN a a) => Relation a a -> Bool
720+partialEquivalence :: (CountableN a, FromListsN a a) => Relation a a -> Bool
715721partialEquivalence r = partialOrder r && equivalence r
716722
717723-- | A 'Relation' @r@ is 'difunctional' or regular wherever
718−-- @r `.` 'conv' r `.` r == r@
724+-- @r ``comp`` 'conv' r ``comp`` r == r@
719725difunctional :: Relation a b -> Bool
720−difunctional r = r . conv r . r == r
726+difunctional r = r `comp` conv r `comp` r == r
721727
722728-- Relational pairing
723729
@@ -726,27 +732,27 @@ difunctional r = r . conv r . r == r
726732-- NOTE: That this is not a true categorical product, see for instance:
727733--
728734-- @
729−-- | 'fstR' `.` 'splitR' a b ``sse`` a
735+-- | 'fstR' ``comp`` 'splitR' a b ``sse`` a
730736-- 'splitR' a b <=> |
731−-- | 'sndR' `.` 'splitR' a b ``sse`` b
737+-- | 'sndR' ``comp`` 'splitR' a b ``sse`` b
732738-- @
733739--
734740-- __Emphasis__ on the 'sse'.
735741--
736742-- @
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)
743+-- 'splitR' r s ``comp`` f == 'splitR' (r ``comp`` f) (s ``comp`` f)
744+-- (R '><' S) ``comp`` 'splitR' p q == 'splitR' (r ``comp`` p) (s ``comp`` q)
745+-- 'conv' ('splitR' r s) ``comp`` 'splitR' x y == ('conv' r ``comp`` x) ``intersection`` ('conv' s ``comp`` y)
740746-- @
741747--
742748-- @
743749-- 'eitherR' ('splitR' r s) ('splitR' t v) == 'splitR' ('eitherR' r t) ('eitherR' s v)
744750-- @
745751splitR ::
746− ( CountableDimsN a b,
752+ ( CountableDimensionsN a b,
747753 CountableN (a, b),
748− FLN (a, b) a,
749− FLN (a, b) b,
754+ FromListsN (a, b) a,
755+ FromListsN (a, b) b,
750756 TrivialP a b
751757 )
752758 => Relation c a -> Relation c b -> Relation c (a, b)
@@ -755,13 +761,13 @@ splitR (R f) (R g) = R (I.kr f g)
755761-- | Relational pairing first component projection
756762--
757763-- @
758−-- 'fstR' `.` 'splitR' r s ``sse`` r
764+-- 'fstR' ``comp`` 'splitR' r s ``sse`` r
759765-- @
760766fstR ::
761767 forall a b .
762− ( CountableDimsN a b,
768+ ( CountableDimensionsN a b,
763769 CountableN (a, b),
764− FLN (a, b) a,
770+ FromListsN (a, b) a,
765771 TrivialP a b
766772 )
767773 => Relation (a, b) a
@@ -770,13 +776,13 @@ fstR = R (I.fstM @Boolean @(I.Normalize a) @(I.Normalize b))
770776-- | Relational pairing second component projection
771777--
772778-- @
773−-- 'sndR' `.` 'splitR' r s ``sse`` s
779+-- 'sndR' ``comp`` 'splitR' r s ``sse`` s
774780-- @
775781sndR ::
776782 forall a b .
777− ( CountableDimsN a b,
783+ ( CountableDimensionsN a b,
778784 CountableN (a, b),
779− FLN (a, b) b,
785+ FromListsN (a, b) b,
780786 TrivialP a b
781787 )
782788 => Relation (a, b) b
@@ -788,17 +794,17 @@ infixl 4 ><
788794-- | Relational pairing functor
789795--
790796-- @
791−-- r '><' s == 'splitR' (r `.` fstR) (s `.` sndR)
792−-- (r '><' s) `.` (p '><' q) == (r `.` p) '><' (s `.` q)
797+-- r '><' s == 'splitR' (r ``comp`` fstR) (s ``comp`` sndR)
798+-- (r '><' s) ``comp`` (p '><' q) == (r ``comp`` p) '><' (s ``comp`` q)
793799-- @
794800(><) ::
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,
801+ ( CountableDimensionsN a b,
802+ CountableDimensionsN c d,
803+ CountableDimensionsN (a, c) (b, d),
804+ FromListsN (a, c) a,
805+ FromListsN (a, c) c,
806+ FromListsN (b, d) b,
807+ FromListsN (b, d) d,
802808 TrivialP a c,
803809 TrivialP b d
804810 )
@@ -810,13 +816,13 @@ infixl 4 ><
810816-- | Relational coproduct.
811817--
812818-- @
813−-- | 'eitherR' a b `.` 'i1' == a
819+-- | 'eitherR' a b ``comp`` 'i1' == a
814820-- 'eitherR' a b <=> |
815−-- | 'eitherR' a b `.` 'i2' == b
821+-- | 'eitherR' a b ``comp`` 'i2' == b
816822-- @
817823--
818824-- @
819−-- 'eitherR' r s `.` 'conv' ('eitherR' t u) == (r `.` 'conv' t) ``union`` (s `.` 'conv' u)
825+-- 'eitherR' r s ``comp`` 'conv' ('eitherR' t u) == (r ``comp`` 'conv' t) ``union`` (s ``comp`` 'conv' u)
820826-- @
821827--
822828-- @
@@ -828,13 +834,13 @@ eitherR = join
828834-- | Relational coproduct first component injection
829835--
830836-- @
831−-- 'img' 'i1' ``union`` 'img' 'i2' == 'id'
832−-- 'i1' `.` 'i2' = 'zeros'
837+-- 'img' 'i1' ``union`` 'img' 'i2' == 'iden'
838+-- 'i1' ``comp`` 'i2' = 'zeros'
833839-- @
834840i1 ::
835− ( CountableDimsN a b,
836− FLN b a,
837− FLN a a
841+ ( CountableDimensionsN a b,
842+ FromListsN b a,
843+ FromListsN a a
838844 )
839845 => Relation a (Either a b)
840846i1 = R I.i1
@@ -842,13 +848,13 @@ i1 = R I.i1
842848-- | Relational coproduct second component injection
843849--
844850-- @
845−-- 'img' 'i1' ``union`` 'img' 'i2' == 'id'
846−-- 'i1' `.` 'i2' = 'zeros'
851+-- 'img' 'i1' ``union`` 'img' 'i2' == 'iden'
852+-- 'i1' ``comp`` 'i2' = 'zeros'
847853-- @
848854i2 ::
849− ( CountableDimsN a b,
850− FLN a b,
851− FLN b b
855+ ( CountableDimensionsN a b,
856+ FromListsN a b,
857+ FromListsN b b
852858 )
853859 => Relation b (Either a b)
854860i2 = R I.i2
@@ -858,14 +864,14 @@ infixl 5 -|-
858864-- | Relational coproduct functor.
859865--
860866-- @
861−-- r '-|-' s == 'eitherR' ('i1' `.` r) ('i2' `.` s)
867+-- r '-|-' s == 'eitherR' ('i1' ``comp`` r) ('i2' ``comp`` s)
862868-- @
863869(-|-) ::
864− ( CountableDimsN b d,
865− FLN b b,
866− FLN d b,
867− FLN b d,
868− FLN d d
870+ ( CountableDimensionsN b d,
871+ FromListsN b b,
872+ FromListsN d b,
873+ FromListsN b d,
874+ FromListsN d d
869875 )
870876 => Relation a b -> Relation c d -> Relation (Either a c) (Either b d)
871877(-|-) (R a) (R b) = R ((I.-|-) a b)
@@ -878,20 +884,20 @@ infixl 5 -|-
878884-- 'trans'/'untrans';
879885-- more-over, where each particular attribute is placed (input/output) is irrelevant.
880886trans ::
881− ( CountableDimsN a b,
887+ ( CountableDimensionsN a b,
882888 CountableN c,
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,
889+ CountableDimensionsN (a, b) (c, b),
890+ FromListsN (c, b) c,
891+ FromListsN (c, b) b,
892+ FromListsN (a, b) a,
893+ FromListsN (a, b) b,
888894 Trivial (a, b),
889895 Trivial (c, b),
890896 TrivialP a b,
891897 TrivialP c b
892898 )
893899 => Relation (a, b) c -> Relation a (c, b)
894−trans r = splitR r sndR . conv fstR
900+trans r = splitR r sndR `comp` conv fstR
895901
896902-- | Relational 'untrans'
897903--
@@ -899,110 +905,107 @@ trans r = splitR r sndR . conv fstR
899905-- 'trans'/'untrans';
900906-- more-over, where each particular attribute is placed (input/output) is irrelevant.
901907untrans ::
902− ( CountableDimsN a b,
908+ ( CountableDimensionsN a b,
903909 CountableN c,
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,
910+ CountableDimensionsN (a, b) (c, b),
911+ FromListsN (c, b) c,
912+ FromListsN (c, b) b,
913+ FromListsN (a, b) b,
914+ FromListsN (a, b) a,
909915 Trivial (a, b),
910916 Trivial (c, b),
911917 TrivialP a b,
912918 TrivialP c b
913919 )
914920 => Relation a (c, b) -> Relation (a, b) c
915−untrans s = fstR . conv (splitR (conv s) sndR)
921+untrans s = fstR `comp` conv (splitR (conv s) sndR)
916922
917923-- | Transforms predicate @p@ into a correflexive relation.
918924--
919925-- @
920−-- 'predR' ('const' True) == 'id'
926+-- 'predR' ('const' True) == 'iden'
921927-- 'predR' ('const' False) == 'zeros'
922928-- @
923929--
924930-- @
925−-- 'predR' q `.` 'predR' p == 'predR' q ``union`` 'predR' p
931+-- 'predR' q ``comp`` 'predR' p == 'predR' q ``union`` 'predR' p
926932-- @
927933predR ::
928934 ( Bounded a,
929935 Enum a,
930− Countable a,
931936 CountableN a,
932− FLN a a,
933− FLN Bool a
937+ FromListsN a a,
938+ FromListsN Bool a
934939 )
935940 => Relation a Bool -> Relation a a
936−predR p = id `intersection` divisionF (fromF (const True)) p
941+predR p = iden `intersection` divisionF (fromF (const True)) p
937942
938943-- | Equalizes functions @f@ and @g@.
939944-- That is, @'equalizer' f g@ is the largest coreflexive
940945-- that restricts @g@ so that @f@ and @g@ yield the same outputs.
941946--
942947-- @
943−-- 'equalizer' r r == 'id'
948+-- 'equalizer' r r == 'iden'
944949-- 'equalizer' ('point' True) ('point' False) == 'zeros'
945950-- @
946951equalizer ::
947952 ( CountableN a,
948− FLN a a
953+ FromListsN a a
949954 )
950955 => Relation a b -> Relation a b -> Relation a a
951−equalizer f g = id `intersection` divisionF f g
956+equalizer f g = iden `intersection` divisionF f g
952957
953958-- | Relational conditional guard.
954959--
955960-- @
956−-- 'guard' p = 'i2' ``overriddenBy`` 'i1' `.` 'predR' p
961+-- 'guard' p = 'i2' ``overriddenBy`` 'i1' ``comp`` 'predR' p
957962-- @
958−guard ::
963+guard ::
959964 ( Bounded b,
960965 Enum b,
961966 CountableN b,
962− Countable b,
963− FLN b b,
964− FLN Bool b
967+ FromListsN b b,
968+ FromListsN Bool b
965969 ) => Relation b Bool -> Relation b (Either b b)
966970guard p = conv (eitherR (predR p) (predR (negate p)))
967971
968972-- | Relational McCarthy's conditional.
969−cond ::
973+cond ::
970974 ( Bounded b,
971975 Enum b,
972− Countable b,
973976 CountableN b,
974− FLN b b,
975− FLN Bool b
976− )
977+ FromListsN b b,
978+ FromListsN Bool b
979+ )
977980 => Relation b Bool -> Relation b c -> Relation b c -> Relation b c
978−cond p r s = eitherR r s . guard p
981+cond p r s = eitherR r s `comp` guard p
979982
980983-- | Relational domain.
981984--
982985-- For injective relations, 'domain' and 'ker'nel coincide,
983−-- since @'ker' r ``sse`` 'id'@ in such situations.
986+-- since @'ker' r ``sse`` 'iden'@ in such situations.
984987domain ::
985988 ( CountableN a,
986− FLN a a
989+ FromListsN a a
987990 ) => Relation a b -> Relation a a
988−domain r = ker r `intersection` id
991+domain r = ker r `intersection` iden
989992
990993-- | Relational range.
991994--
992995-- For functions, 'range' and 'img' (image) coincide,
993−-- since @'img' f ``sse`` id@ for any @f@.
996+-- since @'img' f ``sse`` 'iden'@ for any @f@.
994997range ::
995998 ( CountableN b,
996− FLN b b
999+ FromListsN b b
9971000 ) => Relation a b -> Relation b b
998−range r = img r `intersection` id
1001+range r = img r `intersection` iden
9991002
10001003-- Relation pretty print
10011004
10021005-- | Relation pretty printing
1003−pretty :: (CountableDimsN a b) => Relation a b -> String
1006+pretty :: (CountableDimensionsN a b) => Relation a b -> String
10041007pretty (R a) = I.pretty a
10051008
10061009-- | Relation pretty printing
1007−prettyPrint :: (CountableDimsN a b) => Relation a b -> IO ()
1010+prettyPrint :: (CountableDimensionsN a b) => Relation a b -> IO ()
10081011prettyPrint (R a) = I.prettyPrint a
src/LAoP/Utils.hs+1−4
@@ -96,10 +96,7 @@ module LAoP.Utils
9696 coerceNat3,
9797
9898 -- * List data type
99− List (..),
100−
101− -- * Category type-class
102− Category(..)
99+ List (..)
103100 )
104101where
105102
src/LAoP/Utils/Internal.hs+2−28
@@ -1,9 +1,9 @@
1−{-# LANGUAGE TypeFamilies #-}
21{-# LANGUAGE DeriveGeneric #-}
32{-# LANGUAGE TypeApplications #-}
43{-# LANGUAGE DataKinds #-}
54{-# LANGUAGE FlexibleInstances #-}
65{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6+{-# LANGUAGE KindSignatures #-}
77{-# LANGUAGE ScopedTypeVariables #-}
88
99module LAoP.Utils.Internal
@@ -19,10 +19,7 @@ module LAoP.Utils.Internal
1919 coerceNat3,
2020
2121 -- * 'List' data type
22− List (..),
23−
24− -- * Category type class
25− Category(..)
22+ List (..)
2623 )
2724where
2825
@@ -33,9 +30,6 @@ import Data.Maybe
3330import GHC.TypeLits
3431import Control.DeepSeq
3532import GHC.Generics
36−import Data.Kind
37−import Prelude hiding (id, (.))
38−import qualified Prelude
3933
4034-- | Wrapper around 'Int's that have a restrictive semantic associated.
4135-- A value of type @'Natural' n m@ can only be instanciated with some 'Int'
@@ -174,23 +168,3 @@ instance
174168 fromEnum (L x) =
175169 let as = [minBound .. maxBound]
176170 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.yamldeleted−1
@@ -1 +0,0 @@
1−resolver: lts-15.5
stack.yaml+66−1
@@ -1 +1,66 @@
1−resolver: lts-14.3
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
stack.yaml.lock+4−4
@@ -6,7 +6,7 @@
66packages: []
77snapshots:
88- completed:
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
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
test/Spec.hs+1−7
@@ -1,8 +1,2 @@
1−module Main (main) where
2−
3−import qualified Examples.Readme as RD
4−
51main :: IO ()
6−main = do
7− putStrLn ("Testing if README works" :: String)
8− RD.exec
2+main = putStrLn "Test suite not yet implemented"