express 0.1.6 → 0.1.8
raw patch · 9 files changed
+310/−32 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Express.Fixtures: and' :: Expr -> Expr
+ Data.Express.Fixtures: bs_ :: Expr
+ Data.Express.Fixtures: ll :: Expr
+ Data.Express.Fixtures: mm :: Expr
+ Data.Express.Fixtures: nn :: Expr
+ Data.Express.Fixtures: or' :: Expr -> Expr
+ Data.Express.Fixtures: pps :: Expr
+ Data.Express.Fixtures: product' :: Expr -> Expr
+ Data.Express.Fixtures: qqs :: Expr
+ Data.Express.Fixtures: sum' :: Expr -> Expr
Files
- .github/workflows/build.yml +131/−0
- Makefile +8/−3
- README.md +2/−2
- express.cabal +3/−2
- mk/haskell.mk +10/−11
- src/Data/Express/Canon.hs +39/−11
- src/Data/Express/Fixtures.hs +111/−0
- stack.yaml +1/−1
- test/canon.hs +5/−2
+ .github/workflows/build.yml view
@@ -0,0 +1,131 @@+# Builds and tests this Haskell project on "GitHub Actions"+#+# 2021 Rudy Matela+#+# some docs: https://github.com/haskell/actions/tree/main/setup+name: build+on: [push]+jobs:+ build-and-test:+ runs-on: ubuntu-latest+ steps:++ - name: Cache ~/.cabal/packages+ uses: actions/cache@v2+ with:+ path: ~/.cabal/packages+ key: v1-${{ runner.os }}-cabal-packages-${{ hashFiles('hello.cabal') }}+ restore-keys: v1-${{ runner.os }}-cabal-packages-++ - name: Cache ~/.cabal and ~/.ghc+ uses: actions/cache@v2+ with:+ path: |+ ~/.cabal+ !~/.cabal/packages+ ~/.ghc+ key: v1-${{ runner.os }}-cabal-ghc-latest-${{ hashFiles('hello.cabal') }}+ restore-keys: v1-${{ runner.os }}-cabal-ghc-latest-++ - run: du -hd3 ~/.cabal ~/.ghc || true++ - run: haddock --version || sudo apt-get install ghc-haddock+ - run: ghc --version+ - run: cabal --version++ - name: Check out repository+ uses: actions/checkout@v2++ - run: cabal update+ - run: make install-dependencies++ - run: make+ - run: make test+ - run: make haddock+ - run: make test-sdist+ - run: make test-via-cabal+++ test-with-ghc:+ strategy:+ matrix:+ ghc:+ - '9.0'+ - '8.10'+ - '8.8'+ - '8.6'+ - '8.4'+ - '8.2'+ - '8.0'+ - '7.10'+ - '7.8'+ runs-on: ubuntu-latest+ needs: build-and-test+ container: haskell:${{ matrix.ghc }}+ steps:+ - name: Cache ~/.cabal/packages+ uses: actions/cache@v2+ with:+ path: ~/.cabal/packages+ key: v1-${{ runner.os }}-cabal-packages-${{ hashFiles('hello.cabal') }}+ restore-keys: v1-${{ runner.os }}-cabal-packages-++ - name: Cache ~/.cabal and ~/.ghc+ uses: actions/cache@v2+ with:+ path: |+ ~/.cabal+ !~/.cabal/packages+ ~/.ghc+ key: v1-${{ runner.os }}-cabal-ghc-${{ matrix.ghc }}-${{ hashFiles('hello.cabal') }}+ restore-keys: v1-${{ runner.os }}-cabal-ghc-${{ matrix.ghc }}-++ - run: du -hd3 ~/.cabal ~/.ghc || true++ - run: make --version || rm /etc/apt/sources.list.d/*.list # faster update+ - run: make --version || apt-get update+ - run: make --version || apt-get install make++ - run: ghc --version+ - run: cabal --version++ - name: Check out repository+ uses: actions/checkout@v2++ - run: cabal update+ - run: make install-dependencies++ - run: make+ - run: make test+ - run: make haddock+ - run: make test-sdist+ - run: make test-via-cabal++ test-with-stack:+ runs-on: ubuntu-latest+ needs: build-and-test+ steps:+ - name: Setup Haskell's GHC and Cabal as required by current Stackage LTS+ uses: haskell/actions/setup@v1+ with: # lts-17.9+ ghc-version: '8.10.4'+ cabal-version: '3.2'++ - uses: actions/cache@v2+ with:+ path: ~/.stack+ key: v1-${{ runner.os }}-stack-${{ hashFiles('stack.yaml') }}+ restore-keys: v1-${{ runner.os }}-stack-++ - name: Check out repository+ uses: actions/checkout@v2+ - run: make test-via-stack++ test-with-hugs:+ runs-on: ubuntu-latest+ needs: build-and-test+ steps:+ - run: sudo apt-get install hugs+ - name: Check out repository+ uses: actions/checkout@v2+ - run: make hugs-test
Makefile view
@@ -32,11 +32,11 @@ $(EGS) GHCIMPORTDIRS = src:test GHCFLAGS = -O2 $(shell grep -q "Arch Linux" /etc/lsb-release && echo -dynamic)-HADDOCKFLAGS = --no-print-missing-docs HUGSIMPORTDIRS = .:./src:./test:./etc/hugs-backports:/usr/lib/hugs/packages/* HUGSFLAGS = -98 -h32M RUNPARAMETERS = LIB_DEPS = base template-haskell+INSTALL_DEPS = leancheck all: mk/toplibs @@ -73,10 +73,12 @@ ./test/sdist test-via-cabal:- cabal test+ cabal configure --enable-tests --enable-benchmarks --ghc-options="$(GHCFLAGS) -O0"+ cabal build+ cabal test main test-via-stack:- stack test+ stack test express:test:main --ghc-options="$(GHCFLAGS) -O0" --system-ghc --no-install-ghc --no-terminal diff-test: $(patsubst %,%.diff-test,$(BENCHS)) @@ -89,6 +91,9 @@ ./$< > test/model/$<.out test-via-everything: test test-via-cabal test-via-stack++hugs-test:+ echo 'TBA' legacy-test: # needs ghc-8.8 .. ghc-7.8 installed as such make clean && make test -j GHC=ghc-8.8
README.md view
@@ -366,8 +366,8 @@ [express-logo]: https://github.com/rudymatela/express/raw/master/doc/express.svg?sanitize=true -[build-status]: https://travis-ci.org/rudymatela/express.svg?branch=master-[build-log]: https://travis-ci.org/rudymatela/express+[build-log]: https://github.com/rudymatela/express/actions/workflows/build.yml+[build-status]: https://github.com/rudymatela/express/actions/workflows/build.yml/badge.svg [hackage-version]: https://img.shields.io/hackage/v/express.svg [express-on-hackage]: https://hackage.haskell.org/package/express [stackage-lts-badge]: https://stackage.org/package/express/badge/lts
express.cabal view
@@ -1,6 +1,6 @@ -- Cabal file for express name: express-version: 0.1.6+version: 0.1.8 synopsis: Dynamically-typed expressions involving applications and variables. description: Express is a library for manipulating dynamically typed Haskell expressions.@@ -26,6 +26,7 @@ , doc/express.svg extra-source-files: .gitignore , .travis.yml+ , .github/workflows/build.yml , Makefile , mk/depend.mk , mk/haskell.mk@@ -58,7 +59,7 @@ source-repository this type: git location: https://github.com/rudymatela/express- tag: v0.1.6+ tag: v0.1.8 library exposed-modules: Data.Express
mk/haskell.mk view
@@ -21,6 +21,7 @@ GHC ?= ghc GHCCMD = $(GHC) -i$(GHCIMPORTDIRS) $(GHCFLAGS) HADDOCK ?= haddock+CABAL_INSTALL = $(shell cabal --version | grep -q "version [0-2]\." && echo 'cabal install' || echo 'cabal v1-install') # Hugs Parameters HUGSIMPORTDIRS ?= "/usr/lib/hugs/packages/*"@@ -46,19 +47,13 @@ LIB_DEPS ?= base ALL_DEPS ?= $(LIB_DEPS)+INSTALL_DEPS ?= PKGNAME = $(shell cat *.cabal | grep "^name:" | sed -e "s/name: *//")-HADDOCK_VERSION = $(shell $(HADDOCK) --version | grep version | sed -e 's/.*version //;s/,.*//')-HADDOCK_MAJOR = $(shell echo $(HADDOCK_VERSION) | sed -e 's/\..*//')-HADDOCK_MINOR = $(shell echo $(HADDOCK_VERSION) | sed -e 's/[0-9]*\.\([0-9]*\).[0-9]*/\1/')-HADDOCK_PKG_NAME = $(shell [ $(HADDOCK_MAJOR) -gt 2 ] \- || [ $(HADDOCK_MAJOR) -eq 2 -a $(HADDOCK_MINOR) -ge 20 ] \- && echo "--package-name=$(PKGNAME)")-HADDOCK_HLNK_SRC = $(shell [ $(HADDOCK_MAJOR) -gt 2 ] \- || [ $(HADDOCK_MAJOR) -eq 2 -a $(HADDOCK_MINOR) -ge 17 ] \- && echo "--hyperlinked-source") +HADDOCK_HAS = haddock --help | grep -q -- + # Implicit rules %.hi %.o: %.hs $(GHCCMD) $< && touch $@@@ -94,6 +89,9 @@ depend: find $(ALL_HSS) | ./mk/ghcdeps -i$(GHCIMPORTDIRS) $(GHCFLAGS) > $(DEPMK) +install-dependencies:+ $(CABAL_INSTALL) $(INSTALL_DEPS)+ # haddock rules haddock: doc/index.html @@ -110,8 +108,9 @@ ./mk/haddock-i $(LIB_DEPS) | xargs \ $(HADDOCK) --html -odoc $(LIB_HSS) \ --title=$(PKGNAME) \- $(HADDOCK_PKG_NAME) \- $(HADDOCK_HLNK_SRC) \+ $(shell $(HADDOCK_HAS) --package-name && echo "--package-name=$(PKGNAME)" ) \+ $(shell $(HADDOCK_HAS) --hyperlinked-source && echo "--hyperlinked-source" ) \+ $(shell $(HADDOCK_HAS) --no-print-missing-docs && echo --no-print-missing-docs ) \ $(HADDOCKFLAGS) clean-cabal:
src/Data/Express/Canon.hs view
@@ -171,23 +171,24 @@ -- > [ord 'b' :: Int] -- -- When applying this to expressions already containing variables--- new variables are introduced so name clashes are avoided:+-- clashes are avoided and these variables are not touched: -- -- > > canonicalVariations $ i_ -+- ii -+- jj -+- i_--- > [ x + y + z + x' :: Int--- > , x + y + z + x :: Int ]+-- > [ x + i + j + y :: Int+-- > , x + i + j + y :: Int ] -- -- > > canonicalVariations $ ii -+- jj--- > [x + y :: Int]+-- > [i + j :: Int] -- -- > > canonicalVariations $ xx -+- i_ -+- i_ -+- length' (c_ -:- unit c_) -+- yy--- > [ (((x + y) + z) + length (c:d:"")) + x' :: Int--- > , (((x + y) + z) + length (c:c:"")) + x' :: Int--- > , (((x + y) + y) + length (c:d:"")) + z :: Int--- > , (((x + y) + y) + length (c:c:"")) + z :: Int+-- > [ (((x + z) + x') + length (c:d:"")) + y :: Int+-- > , (((x + z) + x') + length (c:c:"")) + y :: Int+-- > , (((x + z) + z) + length (c:d:"")) + y :: Int+-- > , (((x + z) + z) + length (c:c:"")) + y :: Int -- > ] canonicalVariations :: Expr -> [Expr]-canonicalVariations = map canonicalize . fastCanonicalVariations+canonicalVariations e = map (canonicalizeKeeping (nonHoleVars e))+ $ fastCanonicalVariations e -- | -- Returns the most general canonical variation of an 'Expr'@@ -223,7 +224,8 @@ -- This function is the same as taking the 'head' of 'canonicalVariations' -- but a bit faster. mostGeneralCanonicalVariation :: Expr -> Expr-mostGeneralCanonicalVariation = canonicalize . fastMostGeneralVariation+mostGeneralCanonicalVariation e = canonicalizeKeeping (nonHoleVars e)+ $ fastMostGeneralVariation e -- | -- Returns the most specific canonical variation of an 'Expr'@@ -259,7 +261,8 @@ -- This function is the same as taking the 'last' of 'canonicalVariations' -- but a bit faster. mostSpecificCanonicalVariation :: Expr -> Expr-mostSpecificCanonicalVariation = canonicalize . fastMostSpecificVariation+mostSpecificCanonicalVariation e = canonicalizeKeeping (nonHoleVars e)+ $ fastMostSpecificVariation e -- | -- A faster version of 'canonicalVariations' that@@ -327,6 +330,31 @@ -- | -- Variable names existing in a given Expr.+-- -- This function is not exported. varnames :: Expr -> [String] varnames e = [n | Value ('_':n) _ <- vars e]++-- |+-- Variables that are not holes.+--+-- This function is not exported.+nonHoleVars :: Expr -> [Expr]+nonHoleVars = filter (not . isHole) . nubVars++-- | Canonicalizes an 'Expr' while keeping the given variables untouched.+--+-- > > canonicalizeKeeping [zz] (zz -+- ii -+- jj)+-- > z + x + y :: Int+--+-- > > canonicalizeKeeping [ii,jj] (zz -+- ii -+- jj)+-- > x + i + j :: Int+--+-- This function is not exported.+canonicalizeKeeping :: [Expr] -> Expr -> Expr+canonicalizeKeeping vs e = canonicalizeWith namesFor e+ where+ nm (Value ('_':n) _) = n+ namesFor v | v `elem` vs = nm v : err+ | otherwise = names' v \\ map nm vs+ err = error "Data.Express.canonicalizeKeeping: the impossible happened. This is definitely a bug."
src/Data/Express/Fixtures.hs view
@@ -115,6 +115,7 @@ -- ** Integers , i_, xx, yy, zz, xx' , ii, jj, kk, ii'+ , ll, mm, nn , zero, one, two, three, minusOne, minusTwo , idE, negateE, absE , idInt@@ -164,6 +165,9 @@ , elem' , sort' , insert'+ , bs_, pps, qqs+ , and', or'+ , sum', product' -- ** Maybes , nothing@@ -359,18 +363,56 @@ xx' :: Expr xx' = var "x'" int ++-- | A variable @i@ of 'Int' type.+--+-- > > ii+-- > i :: Int ii :: Expr ii = var "i" int +-- | A variable @j@ of 'Int' type.+--+-- > > jj+-- > j :: Int jj :: Expr jj = var "j" int +-- | A variable @k@ of 'Int' type.+--+-- > > kk+-- > k :: Int kk :: Expr kk = var "k" int +-- | A variable @i'@ of 'Int' type.+--+-- > > ii'+-- > i' :: Int ii' :: Expr ii' = var "i'" int +-- | A variable @l@ of 'Int' type.+--+-- > > ll+-- > l :: Int+ll :: Expr+ll = var "l" int++-- | A variable @m@ of 'Int' type.+--+-- > > mm+-- > m :: Int+mm :: Expr+mm = var "m" int++-- | A variable @n@ of 'Int' type.+--+-- > > nn+-- > n :: Int+nn :: Expr+nn = var "n" int+ -- | The value @0@ bound to the 'Int' type encoded as an 'Expr'. -- -- > > zero@@ -1098,6 +1140,75 @@ sixtuple e1 e2 e3 e4 e5 e6 = cccccE :$ e1 :$ e2 :$ e3 :$ e4 :$ e5 :$ e6 where cccccE = value ",,,,," ((,,,,,) :: Int -> Int -> Int -> Int -> Int -> Int -> (Int,Int,Int,Int,Int,Int))++-- | A typed hole of @[Bool]@ type encoded as an 'Expr'.+--+-- > > bs_+-- > _ :: [Bool]+bs_ :: Expr+bs_ = hole [bool]++-- | 'Expr' representing a variable @p' :: `[Bool]`@.+--+-- > > pps+-- > ps :: [Bool]+pps :: Expr+pps = var "ps" [bool]++-- | A typed hole of '[Bool]' type+--+-- > > qqs+-- > qs :: [Bool]+qqs :: Expr+qqs = var "qs" [bool]++-- | 'and' lifted over the 'Expr' type.+--+-- > > and' pps+-- > and ps :: Bool+--+-- > > evl (and' $ expr [False,True]) :: Bool+-- > False+and' :: Expr -> Expr+and' e = andE :$ e+ where+ andE = value "and" (and :: [Bool] -> Bool)++-- | 'or' lifted over the 'Expr' type.+--+-- > > or' pps+-- > or ps :: Bool+--+-- > > evl (or' $ expr [False,True]) :: Bool+-- > True+or' :: Expr -> Expr+or' e = orE :$ e+ where+ orE = value "or" (or :: [Bool] -> Bool)++-- | 'sum' of 'Int' elements lifted over the 'Expr' type.+--+-- > > sum' xxs+-- > sum xs :: Int+--+-- > > evl (sum' $ expr [1,2,3::Int]) :: Int+-- > 6+sum' :: Expr -> Expr+sum' e = sumE :$ e+ where+ sumE = value "sum" (sum :: [Int] -> Int)++-- | 'product' of 'Int' elements lifted over the 'Expr' type.+--+-- > > product' xxs+-- > product xs :: Int+--+-- > > evl (product' $ expr [1,2,3::Int]) :: Int+-- > 6+product' :: Expr -> Expr+product' e = productE :$ e+ where+ productE = value "product" (product :: [Int] -> Int) headOr :: a -> [a] -> a headOr x [] = x
stack.yaml view
@@ -1,4 +1,4 @@-resolver: lts-15.5 # or ghc-8.8.3+resolver: lts-17.9 # or ghc-8.10.4 packages: - .
test/canon.hs view
@@ -88,8 +88,11 @@ , xx -+- xx -+- xx -+- xx ] , canonicalVariations (i_ -+- ii -+- jj -+- i_)- == [ xx -+- yy -+- zz -+- xx'- , xx -+- yy -+- zz -+- xx ]+ == [ xx -+- ii -+- jj -+- yy+ , xx -+- ii -+- jj -+- xx ]+ , canonicalVariations (i_ -+- xx -+- yy -+- i_)+ == [ zz -+- xx -+- yy -+- xx'+ , zz -+- xx -+- yy -+- zz ] , holds n $ \e -> let xs = map (length . nubVars) $ canonicalVariations e