packages feed

express 0.1.3 → 0.1.4

raw patch · 53 files changed

+426/−153 lines, 53 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Express: fastMostGeneralVariation :: Expr -> Expr
+ Data.Express: fastMostSpecificVariation :: Expr -> Expr
+ Data.Express: fill :: Expr -> [Expr] -> Expr
+ Data.Express: isFun :: Expr -> Bool
+ Data.Express: mostGeneralCanonicalVariation :: Expr -> Expr
+ Data.Express: mostSpecificCanonicalVariation :: Expr -> Expr
+ Data.Express.Canon: fastMostGeneralVariation :: Expr -> Expr
+ Data.Express.Canon: fastMostSpecificVariation :: Expr -> Expr
+ Data.Express.Canon: mostGeneralCanonicalVariation :: Expr -> Expr
+ Data.Express.Canon: mostSpecificCanonicalVariation :: Expr -> Expr
+ Data.Express.Core: isFun :: Expr -> Bool
+ Data.Express.Fixtures: if' :: Expr -> Expr -> Expr -> Expr
+ Data.Express.Fixtures: infixl 7 -*-
+ Data.Express.Fixtures: infixr 0 -==>-
+ Data.Express.Fixtures: infixr 2 -||-
+ Data.Express.Fixtures: infixr 3 -&&-
+ Data.Express.Fixtures: null' :: Expr -> Expr
+ Data.Express.Hole: fill :: Expr -> [Expr] -> Expr

Files

.travis.yml view
@@ -1,6 +1,6 @@ # .travis.yml file for Express #-# Copyright:   (c) 2017-2020 Rudy Matela+# Copyright:   (c) 2017-2021 Rudy Matela # License:     3-Clause BSD  (see the file LICENSE) # Maintainer:  Rudy Matela <rudy@matela.com.br> @@ -48,11 +48,17 @@   - ghc: 'head'   include:   - ghc: 'head'-    env:                   GHCVER=head         CABALVER=head   STACKVER=nightly-2020-03-28-    addons: {apt: {packages: [ghc-head,   cabal-install-head], sources: hvr-ghc}}+    env:                   GHCVER=head        CABALVER=head    STACKVER=nightly-2021-04-06+    addons: {apt: {packages: [ghc-head,  cabal-install-head],  sources: hvr-ghc}}+  - ghc: '9.0'+    env:                   GHCVER=9.0.1       CABALVER=head    STACKVER=nightly-2021-04-06+    addons: {apt: {packages: [ghc-9.0.1, cabal-install-head],  sources: hvr-ghc}}+  - ghc: '8.10'+    env:                   GHCVER=8.10.4       CABALVER=3.2    STACKVER=lts-17.9+    addons: {apt: {packages: [ghc-8.10.4, cabal-install-3.2],  sources: hvr-ghc}}   - ghc: '8.8'-    env:                   GHCVER=8.8.3        CABALVER=3.0    STACKVER=lts-15.5-    addons: {apt: {packages: [ghc-8.8.3,  cabal-install-3.0],  sources: hvr-ghc}}+    env:                   GHCVER=8.8.4        CABALVER=3.0    STACKVER=lts-16.31+    addons: {apt: {packages: [ghc-8.8.4,  cabal-install-3.0],  sources: hvr-ghc}}   - ghc: '8.6'     env:                   GHCVER=8.6.5        CABALVER=2.4    STACKVER=lts-14.27     addons: {apt: {packages: [ghc-8.6.5,  cabal-install-2.4],  sources: hvr-ghc}}
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2019-2020, Rudy Matela+Copyright (c) 2019-2021, Rudy Matela  All rights reserved. 
Makefile view
@@ -1,6 +1,6 @@ # Makefile for express #-# Copyright:   (c) 2015-2018 Rudy Matela+# Copyright:   (c) 2015-2021 Rudy Matela # License:     3-Clause BSD  (see the file LICENSE) # Maintainer:  Rudy Matela <rudy@matela.com.br> TESTS = \@@ -89,14 +89,20 @@  test-via-everything: test test-via-cabal test-via-stack -legacy-test: # needs ghc-8.0 .. ghc-7.8 installed as such-	make clean  &&  make test GHC=ghc-8.2  GHCFLAGS="-Werror -dynamic"-	make clean  &&  make test GHC=ghc-8.0  GHCFLAGS="-Werror -dynamic"-	make clean  &&  make test GHC=ghc-7.10 GHCFLAGS="-Werror -dynamic"-	make clean  &&  make test GHC=ghc-7.8  GHCFLAGS="-Werror -dynamic"-	make clean  &&  make test+legacy-test: # needs ghc-8.8 .. ghc-7.8 installed as such+	make clean  &&  make test -j GHC=ghc-8.8+	make clean  &&  make test -j GHC=ghc-8.6+	make clean  &&  make test -j GHC=ghc-8.4+	make clean  &&  make test -j GHC=ghc-8.2+	make clean  &&  make test -j GHC=ghc-8.0+	make clean  &&  make test -j GHC=ghc-7.10+	make clean  &&  make test -j GHC=ghc-7.8+	make clean  &&  make test -j  legacy-test-via-cabal: # needs similarly named cabal wrappers+	cabal clean  &&  cabal-ghc-8.8  configure  &&  cabal-ghc-8.8  test+	cabal clean  &&  cabal-ghc-8.6  configure  &&  cabal-ghc-8.6  test+	cabal clean  &&  cabal-ghc-8.4  configure  &&  cabal-ghc-8.4  test 	cabal clean  &&  cabal-ghc-8.2  configure  &&  cabal-ghc-8.2  test 	cabal clean  &&  cabal-ghc-8.0  configure  &&  cabal-ghc-8.0  test 	cabal clean  &&  cabal-ghc-7.10 configure  &&  cabal-ghc-7.10 test@@ -104,13 +110,19 @@ 	cabal clean  &&  cabal test  prepare:-	cabal update  &&  cabal install leancheck+	cabal update+	cabal install $(ALL_DEPS) --lib  prepare-legacy-test:-	cabal-ghc-8.2  update  &&  cabal-ghc-8.2  install leancheck-	cabal-ghc-8.0  update  &&  cabal-ghc-8.0  install leancheck-	cabal-ghc-7.10 update  &&  cabal-ghc-7.10 install leancheck-	cabal-ghc-7.8  update  &&  cabal-ghc-7.8  install leancheck+	cabal update+	cabal-ghc-8.8  install $(ALL_DEPS) --lib+	cabal-ghc-8.6  install $(ALL_DEPS) --lib+	cabal-ghc-8.4  install $(ALL_DEPS) --lib+	cabal-ghc-8.2  install $(ALL_DEPS) --lib+	cabal-ghc-8.0  install $(ALL_DEPS) --lib+	cabal-ghc-7.10 v1-install $(ALL_DEPS)+	cabal-ghc-7.8  v1-install $(ALL_DEPS)+	# (v2-) library installation is supported on GHC 8.0+ only)  hlint: 	hlint \
README.md view
@@ -29,6 +29,11 @@ 	$ cabal update 	$ cabal install express +Starting from Cabal v3.0, you need to pass `--lib` as an argument to cabal+install:++	$ cabal install leancheck --lib+  Basics ------
bench/compare.hs view
@@ -1,6 +1,6 @@ -- ord.hs -- prints results of the Ord Expr's instance ----- Copyright (c) 2019 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test import System.Environment (getArgs)
bench/pairs.hs view
@@ -1,6 +1,6 @@ -- pairs.hs -- a thousand pairs of expressions ----- Copyright (c) 2019 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test import System.Environment (getArgs)
bench/tiers.hs view
@@ -1,6 +1,6 @@ -- tiers.hs -- prints tiers of expressions ----- Copyright (c) 2019 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test import Data.List (intercalate, nub)
eg/u-extrapolate.hs view
@@ -1,6 +1,6 @@ -- u-extrapolate.hs -- micro Extrapolate / Extrapolite ----- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). -- -- A small property-based testing library capable of generalizing
eg/u-speculate.hs view
@@ -1,6 +1,6 @@--- u-extrapolate.hs -- micro Speculate / Speculite+-- u-speculate.hs -- micro Speculate / Speculite ----- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). -- -- A small library capable of conjecturing laws about Haskell functions@@ -16,7 +16,7 @@ -- * even with pruning, this program still prints some redundant rules; -- * there is no way to configure maximum number of tests to consider an --   equation true;--- * runtime is exponential as you add more symbols to Speculate about.+-- * runtime is exponential as you add more symbols to speculate about. -- -- Please see Speculate for a full featured version: --
express.cabal view
@@ -1,6 +1,6 @@ -- Cabal file for express name: express-version: 0.1.3+version: 0.1.4 synopsis: Dynamically-typed expressions involving applications and variables. description:   Express is a library for manipulating dynamically typed Haskell expressions.@@ -58,7 +58,7 @@ source-repository this   type:           git   location:       https://github.com/rudymatela/express-  tag:            v0.1.3+  tag:            v0.1.4  library   exposed-modules:     Data.Express
mk/depend.mk view
@@ -174,8 +174,6 @@   src/Data/Express/Fold.hs \   src/Data/Express/Core.hs \   src/Data/Express/Basic.hs-src/Data/Express/Canon: \-  mk/toplibs src/Data/Express/Canon.o: \   src/Data/Express/Utils/Typeable.hs \   src/Data/Express/Utils/String.hs \@@ -235,6 +233,8 @@   src/Data/Express/Utils/List.hs \   src/Data/Express/Fold.hs \   src/Data/Express/Core.hs+src/Data/Express/Hole: \+  mk/toplibs src/Data/Express/Hole.o: \   src/Data/Express/Utils/Typeable.hs \   src/Data/Express/Utils/String.hs \
mk/ghcdeps view
@@ -2,7 +2,7 @@ # # ghcdeps: generate Haskell make dependencies for compiling with GHC. #-# Copyright (c) 2015-2020 Rudy Matela.+# Copyright (c) 2015-2021 Rudy Matela. # Distributed under the 3-Clause BSD licence. # # From a list of files provided on standard input,@@ -46,4 +46,5 @@ 	rm -f tmp.mk done | sort |+grep -v "^Loaded package environment from " | sed -e 's,  *, \\\n  ,g'
mk/haddock-i view
@@ -2,7 +2,7 @@ # # haddock-i: list haddock's -i parameters. #-# Copyright (c) 2015-2020 Rudy Matela.+# Copyright (c) 2015-2021 Rudy Matela. # Distributed under the 3-Clause BSD licence. # # $ haddock-i <package1> <package2> ... <packageN>
mk/haskell.mk view
@@ -1,6 +1,6 @@ # Implicit rules for compiling Haskell code. #-# Copyright (c) 2015-2020 Rudy Matela.+# Copyright (c) 2015-2021 Rudy Matela. # Distributed under the 3-Clause BSD licence. # # You can optionally configure the "Configuration variables" below in your main
mk/install-on view
@@ -2,9 +2,12 @@ # # mk/install-on: install or updates the mk folder on a Haskell project #+# Copyright (c) 2019-2021 Rudy Matela.+# Distributed under the 3-Clause BSD licence.+# # usage: ./mk/install-on path/to/project #-# This assumes a few things:+# This script assumes that: # # * tests are stored in a "test/" folder # * sources are stored in a "src/" folder
src/Data/Express.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --@@ -140,6 +140,7 @@   , isConst   , isIllTyped   , isWellTyped+  , isFun   , hasVar   , isGround @@ -196,7 +197,7 @@   , holes   , nubHoles   , holeAsTypeOf-+  , fill    -- -- -- Data.Express.Fold exports -- -- -- @@ -222,7 +223,11 @@   , isCanonical   , isCanonicalWith   , canonicalVariations+  , mostGeneralCanonicalVariation+  , mostSpecificCanonicalVariation   , fastCanonicalVariations+  , fastMostGeneralVariation+  , fastMostSpecificVariation    -- -- -- Data.Express.Match exports -- -- -- 
src/Data/Express/Basic.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Basic--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Canon.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Canon--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --@@ -13,7 +13,11 @@   , isCanonical   , isCanonicalWith   , canonicalVariations+  , mostGeneralCanonicalVariation+  , mostSpecificCanonicalVariation   , fastCanonicalVariations+  , fastMostGeneralVariation+  , fastMostSpecificVariation   ) where @@ -175,6 +179,84 @@ canonicalVariations = map canonicalize . fastCanonicalVariations  -- |+-- Returns the most general canonical variation of an 'Expr'+-- by filling holes with variables.+--+-- > > mostGeneralCanonicalVariation $ i_+-- > x :: Int+--+-- > > mostGeneralCanonicalVariation $ i_ -+- i_+-- > x + y :: Int+--+-- > > mostGeneralCanonicalVariation $ i_ -+- i_ -+- i_+-- > (x + y) + z :: Int+--+-- > > mostGeneralCanonicalVariation $ i_ -+- ord' c_+-- > x + ord c :: Int+--+-- > > mostGeneralCanonicalVariation $ i_ -+- i_ -+- ord' c_+-- > (x + y) + ord c :: Int+--+-- > > mostGeneralCanonicalVariation $ i_ -+- i_ -+- length' (c_ -:- unit c_)+-- > (x + y) + length (c:d:"") :: Int+--+-- In an expression without holes this functions just returns+-- the given expression itself:+--+-- > > mostGeneralCanonicalVariation $ val (0 :: Int)+-- > 0 :: Int+--+-- > > mostGeneralCanonicalVariation $ ord' bee+-- > ord 'b' :: Int+--+-- Behaviour is undefined when applying this function to expressions already+-- containing variables.+--+-- This function is the same as taking the 'head' of 'canonicalVariations'+-- but a bit faster.+mostGeneralCanonicalVariation :: Expr -> Expr+mostGeneralCanonicalVariation  =  canonicalize . fastMostGeneralVariation++-- |+-- Returns the most specific canonical variation of an 'Expr'+-- by filling holes with variables.+--+-- > > mostSpecificCanonicalVariation $ i_+-- > x :: Int+--+-- > > mostSpecificCanonicalVariation $ i_ -+- i_+-- > x + x :: Int+--+-- > > mostSpecificCanonicalVariation $ i_ -+- i_ -+- i_+-- > (x + x) + x :: Int+--+-- > > mostSpecificCanonicalVariation $ i_ -+- ord' c_+-- > x + ord c :: Int+--+-- > > mostSpecificCanonicalVariation $ i_ -+- i_ -+- ord' c_+-- > (x + x) + ord c :: Int+--+-- > > mostSpecificCanonicalVariation $ i_ -+- i_ -+- length' (c_ -:- unit c_)+-- > (x + x) + length (c:c:"") :: Int+--+-- In an expression without holes this functions just returns+-- the given expression itself:+--+-- > > mostSpecificCanonicalVariation $ val (0 :: Int)+-- > 0 :: Int+--+-- > > mostSpecificCanonicalVariation $ ord' bee+-- > ord 'b' :: Int+--+-- Behaviour is undefined when applying this function to expressions already+-- containing variables.+--+-- This function is the same as taking the 'last' of 'canonicalVariations'+-- but a bit faster.+mostSpecificCanonicalVariation :: Expr -> Expr+mostSpecificCanonicalVariation  =  canonicalize . fastMostSpecificVariation++-- | -- A faster version of 'canonicalVariations' that -- disregards name clashes across different types. -- Results are confusing to the user@@ -216,19 +298,20 @@            : [ map (n `varAsTypeOf` h:) (fillings i hs) -- no new variable              | n <- take i names ] +-- |+-- A faster version of 'mostGeneralCanonicalVariation'+-- that disregards name clashes across different types.+-- Consider using 'mostGeneralCanonicalVariation' instead.+--+-- The same caveats of 'fastCanonicalVariations' do apply here.+fastMostGeneralVariation :: Expr -> Expr+fastMostGeneralVariation e  =  fill e (zipWith varAsTypeOf (variableNamesFromTemplate "x") (holes e)) --- | Fill holes in an expression.---   Silently skips holes that are not of the right type.---   Silently discard remaining expressions.-fill :: Expr -> [Expr] -> Expr-fill e = fst . fill' e-  where-  fill' :: Expr -> [Expr] -> (Expr,[Expr])-  fill' (e1 :$ e2) es = let (e1',es')  = fill' e1 es-                            (e2',es'') = fill' e2 es'-                        in (e1' :$ e2', es'')-  fill' eh (e:es) | isHole eh && typ eh == typ e = (e,es)-  fill' e es = (e,es)--- TODO: copy tests from Speculate--- TODO: add examples on Haddock--- TODO: export? consider exporting 'fill' from the Hole module+-- |+-- A faster version of 'mostSpecificCanonicalVariation'+-- that disregards name clashes across different types.+-- Consider using 'mostSpecificCanonicalVariation' instead.+--+-- The same caveats of 'fastCanonicalVariations' do apply here.+fastMostSpecificVariation :: Expr -> Expr+fastMostSpecificVariation e  =  fill e (map ("x" `varAsTypeOf`) (holes e))
src/Data/Express/Core.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Core--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --@@ -42,6 +42,7 @@   , isConst   , isIllTyped   , isWellTyped+  , isFun   , hasVar   , isGround @@ -324,6 +325,21 @@ isWellTyped :: Expr -> Bool isWellTyped  =  isJust . mtyp +-- | /O(n)/.+-- Returns whether the given 'Expr' is of a functional type.+-- This is the same as checking if the 'arity' of the given 'Expr' is non-zero.+--+-- > > isFun (value "abs" (abs :: Int -> Int))+-- > True+--+-- > > isFun (val (1::Int))+-- > False+--+-- > > isFun (value "const" (const :: Bool -> Bool -> Bool) :$ val False)+-- > True+isFun :: Expr -> Bool+isFun  =  isFunTy . typ+ -- |  /O(n)/. -- 'Just' the value of an expression when possible (correct type), -- 'Nothing' otherwise.@@ -430,24 +446,26 @@ showsPrecExpr d (Value s _) | isNegativeLiteral s = showParen (d > 0) $ showString s showsPrecExpr d (Value s _) = showParen sp $ showString s   where sp = if atomic s then isInfix s else maybe True (d >) $ outernmostPrec s-showsPrecExpr d ((Value ":" _ :$ e1) :$ e2)+showsPrecExpr d (Value ":" _ :$ e1 :$ e2)   | isConst e1 && mtyp e1 == Just (typeOf (undefined :: Char)) =   case showsTailExpr e2 "" of     '\"':cs  -> showString ("\"" ++ (init . tail) (showsPrecExpr 0 e1 "") ++ cs)     cs -> showParen (d > prec ":")         $ showsOpExpr ":" e1 . showString ":" . showString cs-showsPrecExpr d ((Value ":" _ :$ e1) :$ e2) =+showsPrecExpr d (Value ":" _ :$ e1 :$ e2) =   case showsTailExpr e2 "" of     "[]" -> showString "[" . showsPrecExpr 0 e1 . showString "]"     '[':cs -> showString "[" . showsPrecExpr 0 e1 . showString "," . showString cs     cs -> showParen (d > prec ":")         $ showsOpExpr ":" e1 . showString ":" . showString cs-showsPrecExpr d ee | isTuple ee = id-    showString "("-  . foldr1 (\s1 s2 -> s1 . showString "," . s2)-           (showsPrecExpr 0 `map` unfoldTuple ee)-  . showString ")"-showsPrecExpr d ((Value f' _ :$ e1) :$ e2)+showsPrecExpr d ee | isTuple ee = showParen True+                                $ foldr1 (\s1 s2 -> s1 . showString "," . s2)+                                         (showsPrecExpr 0 `map` unfoldTuple ee)+showsPrecExpr d (Value "if" _ :$ ep :$ ex :$ ey) =+  showParen (d >= 0) $ showString "if "    . showsPrecExpr 0 ep+                     . showString " then " . showsPrecExpr 0 ex+                     . showString " else " . showsPrecExpr 0 ey+showsPrecExpr d (Value f' _ :$ e1 :$ e2)   | isInfix f = showParen (d > prec f)               $ showsOpExpr f e1               . showString " " . showString f . showString " "@@ -461,8 +479,7 @@                  ('_':f) -> f -- on variables we drop the preceding _                  f -> f       -- constants as themselves showsPrecExpr d (Value f' _ :$ e1)-  | isInfix f = showParen True-              $ showsOpExpr f e1 . showString " " . showString f+  | isInfix f = showParen True $ showsOpExpr f e1 . showString " " . showString f   where   f = case f' of "_" -> "_"   -- holes are shown as _                  ('_':f) -> f -- on variables we drop the preceding _@@ -474,12 +491,12 @@  -- bad smell here, repeated code! showsTailExpr :: Expr -> String -> String-showsTailExpr ((Value ":" _ :$ e1) :$ e2)+showsTailExpr (Value ":" _ :$ e1 :$ e2)   | isConst e1 && mtyp e1 == Just (typeOf (undefined :: Char)) =   case showsPrecExpr 0 e2 "" of     '\"':cs  -> showString ("\"" ++ (init . tail) (showsPrecExpr 0 e1 "") ++ cs)     cs -> showsOpExpr ":" e1 . showString ":" . showsTailExpr e2-showsTailExpr ((Value ":" _ :$ e1) :$ e2) =+showsTailExpr (Value ":" _ :$ e1 :$ e2) =   case showsPrecExpr 0 e2 "" of     "[]" -> showString "[" . showsPrecExpr 0 e1 . showString "]"     '[':cs -> showString "[" . showsPrecExpr 0 e1 . showString "," . showString cs@@ -506,7 +523,7 @@ -- > > putStrLn $ showExpr $ (pp -||- true) -&&- (qq -||- false) -- > (p || True) && (q || False) showExpr :: Expr -> String-showExpr = showPrecExpr 0+showExpr = showPrecExpr (-1)  -- | /O(n)/. --   Does not evaluate values when comparing, but rather uses their@@ -786,7 +803,7 @@   s e@(e1 :$ e2)  =  (e:) . s e1 . s e2   s e             =  (e:) --- | /O(n log n)/ for the spine, /O(n^2)/ for full evaluation.+-- | Average /O(n log n)/ for the spine, /O(n^2)/ for full evaluation. -- Lists all subexpressions of a given expression without repetitions. -- This includes the expression itself and partial function applications. -- (cf. 'subexprs')@@ -807,16 +824,14 @@ -- > , p && True :: Bool -- > , p && (p && True) :: Bool -- > ]+--+-- While this is /O(n log n)/ on average it is /O(n^2)/ in the worst-case+-- (f (g (h (i (j (k (l (m (n x))))))))). nubSubexprs :: Expr -> [Expr] nubSubexprs  =  s   where   s e@(e1 :$ e2)  =  [e] +++ s e1 +++ s e2   s e             =  [e]--- TODO: After deciding if I'll stick to this implementation or the old one,--- add note about complexity:------ While this is /O(n log n)/ on average it is /O(n^2)/ in the worst-case.--- Worst case = f (g (h (i (j (k (l (m (n x))))))))  -- | /O(n)/. -- Lists all terminal values in an expression in order and with repetitions.
src/Data/Express/Express.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Express--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Express/Derive.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE TemplateHaskell, CPP #-} -- | -- Module      : Data.Express.Express.Derive--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Fixtures.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Fixtures--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --@@ -110,6 +110,7 @@   , (-<=-)   , (-<-)   , compare'+  , if'    -- ** Integers   , i_, xx, yy, zz, xx'@@ -158,6 +159,7 @@   , (-++-)   , head'   , tail'+  , null'   , length'   , elem'   , sort'@@ -273,6 +275,7 @@  (-==>-) :: Expr -> Expr -> Expr e1 -==>- e2  =  implies :$ e1 :$ e2+infixr 0 -==>-  implies :: Expr implies  =  value "==>" (==>)@@ -305,6 +308,7 @@ -- > False (-&&-) :: Expr -> Expr -> Expr pp -&&- qq  =  andE :$ pp :$ qq+infixr 3 -&&-  -- | The function '||' lifted over the 'Expr' type. --@@ -318,6 +322,7 @@ -- > True (-||-) :: Expr -> Expr -> Expr pp -||- qq  =  orE :$ pp :$ qq+infixr 2 -||-  -- | A typed hole of 'Int' type. --@@ -504,6 +509,7 @@ -- > 2 * x :: Int (-*-) :: Expr -> Expr -> Expr e1 -*- e2 = times :$ e1 :$ e2+infixl 7 -*-  -- | The operator '*' for the 'Int' type.  (See also '-*-'.) --@@ -851,6 +857,26 @@   where   err  =  error $ "tail': unhandled type " ++ show (typ exs) +-- | List 'null' lifted over the 'Expr' type.+--   Works for the element types 'Int', 'Char' and 'Bool'.+--+-- > > null' $ unit one+-- > null [1] :: Bool+--+-- > > null' $ nil+-- > null [] :: Bool+--+-- > > evl $ null' nil :: Bool+-- > True+null' :: Expr -> Expr+null' exs = headOr err $ mapMaybe ($$ exs)+  [ value "null" (null :: [Int] -> Bool)+  , value "null" (null :: [Char] -> Bool)+  , value "null" (null :: [Bool] -> Bool)+  ]+  where+  err  =  error $ "null': unhandled type " ++ show (typ exs)+ -- | List 'length' lifted over the 'Expr' type. --   Works for the element types 'Int', 'Char' and 'Bool'. --@@ -971,6 +997,36 @@   where   err  =  error $ "(-<-): unhandled type " ++ show (typ ex) infix 4 -<-++-- | A virtual function @if :: Bool -> a -> a -> a@ lifted over the 'Expr' type.+--   This is displayed as an if-then-else.+--+-- > > if' pp zero xx+-- > (if p then 0 else x) :: Int+--+-- > > zz -*- if' pp xx yy+-- > z * (if p then x else y) :: Int+--+-- > > if' pp false true -||- if' qq true false+-- > (if p then False else True) || (if q then True else False) :: Bool+--+-- > > evl $ if' true (val 't') (val 'f') :: Char+-- > 't'+if' :: Expr -> Expr -> Expr -> Expr+if' ep ex ey  =  (:$ ey) . headOr err . mapMaybe ($$ ex) $ map (:$ ep)+  [ value "if" (iff :: If ())+  , value "if" (iff :: If Int)+  , value "if" (iff :: If Bool)+  , value "if" (iff :: If Char)+  , value "if" (iff :: If [Int])+  , value "if" (iff :: If [Bool])+  , value "if" (iff :: If [Char])+  ]+  where+  err  =  error $ "if': unhandled type " ++ show (typ ex)+  iff :: Bool -> a -> a -> a+  iff p x y  =  if p then x else y+type If a = Bool -> a -> a -> a  compare' :: Expr -> Expr -> Expr compare' ex ey  =  (:$ ey) . headOr err $ mapMaybe ($$ ex)
src/Data/Express/Fold.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Fold--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --@@ -128,6 +128,6 @@ -- > > unfold $ expr [1,2,3::Int] -- > [1 :: Int,2 :: Int,3 :: Int] unfold :: Expr -> [Expr]-unfold   (Value "[]" _)               =  []-unfold (((Value ":"  _) :$ e) :$ es)  =  e : unfold es+unfold (Value "[]" _)             =  []+unfold (Value ":"  _ :$ e :$ es)  =  e : unfold es unfold e  =  error $ "unfold: cannot unfold expression: " ++ show e
src/Data/Express/Hole.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Hole--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --@@ -19,6 +19,7 @@   , holes   , nubHoles   , holeAsTypeOf+  , fill   ) where @@ -178,3 +179,47 @@ -- > ] listVarsAsTypeOf :: String -> Expr -> [Expr] listVarsAsTypeOf s e  =  map (`varAsTypeOf` e) (variableNamesFromTemplate s)+++-- | Fill holes in an expression with the given list.+--+-- > > let i_  =  hole (undefined :: Int)+-- > > let e1 -+- e2  =  value "+" ((+) :: Int -> Int -> Int) :$ e1 :$ e2+-- > > let xx  =  var "x" (undefined :: Int)+-- > > let yy  =  var "y" (undefined :: Int)+--+-- > > fill (i_ -+- i_) [xx, yy]+-- > x + y :: Int+--+-- > > fill (i_ -+- i_) [xx, xx]+-- > x + x :: Int+--+-- > > let one  =  val (1::Int)+--+-- > > fill (i_ -+- i_) [one, one -+- one]+-- > 1 + (1 + 1) :: Int+--+-- This function silently remaining expressions:+--+-- > > fill i_ [xx, yy]+-- > x :: Int+--+-- This function silently keeps remaining holes:+--+-- > > fill (i_ -+- i_ -+- i_) [xx, yy]+-- > (x + y) + _ :: Int+--+-- This function silently skips remaining holes+-- if one is not of the right type:+--+-- > > fill (i_ -+- i_ -+- i_) [xx, val 'c', yy]+-- > (x + _) + _ :: Int+fill :: Expr -> [Expr] -> Expr+fill e = fst . fill' e+  where+  fill' :: Expr -> [Expr] -> (Expr,[Expr])+  fill' (e1 :$ e2) es = let (e1',es')  = fill' e1 es+                            (e2',es'') = fill' e2 es'+                        in (e1' :$ e2', es'')+  fill' eh (e:es) | isHole eh && typ eh == typ e = (e,es)+  fill' e es = (e,es)
src/Data/Express/Instances.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Instances--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Map.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Map--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Match.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Match--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Name.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Name--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Name/Derive.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE TemplateHaskell, CPP #-} -- | -- Module      : Data.Express.Name.Derive--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Utils/List.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Utils.List--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Utils/String.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Utils.String--- Copyright   : (c) 2016-2020 Rudy Matela+-- Copyright   : (c) 2016-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --@@ -91,38 +91,38 @@  -- | Returns the precedence of default Haskell operators prec :: String -> Int-prec " "  = 10-prec "!!" = 9-prec "."  = 9-prec "^"  = 8-prec "^^" = 8-prec "**" = 8-prec "*"  = 7-prec "/"  = 7-prec "%"  = 7-prec "+"  = 6-prec "-"  = 6-prec ":"  = 5-prec "++" = 5-prec "\\" = 5-prec ">"  = 4-prec "<"  = 4-prec ">=" = 4-prec "<=" = 4-prec "==" = 4-prec "/=" = 4-prec "`elem`" = 4-prec "&&" = 3-prec "||" = 2-prec ">>=" = 1-prec ">>" = 1-prec ">=>" = 1-prec "<=<" = 1-prec "$"  = 0-prec "`seq`" = 0-prec "==>" = 0-prec "<==>" = 0-prec _ = 9+prec " "       =  10+prec "!!"      =   9+prec "."       =   9+prec "^"       =   8+prec "^^"      =   8+prec "**"      =   8+prec "*"       =   7+prec "/"       =   7+prec "%"       =   7+prec "+"       =   6+prec "-"       =   6+prec ":"       =   5+prec "++"      =   5+prec "\\"      =   5+prec ">"       =   4+prec "<"       =   4+prec ">="      =   4+prec "<="      =   4+prec "=="      =   4+prec "/="      =   4+prec "`elem`"  =   4+prec "&&"      =   3+prec "||"      =   2+prec ">>="     =   1+prec ">>"      =   1+prec ">=>"     =   1+prec "<=<"     =   1+prec "$"       =   0+prec "`seq`"   =   0+prec "==>"     =   0+prec "<==>"    =   0+prec _         =   9  isPrefix :: String -> Bool isPrefix = not . isInfix
src/Data/Express/Utils/TH.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE TemplateHaskell, CPP #-} -- | -- Module      : Data.Express.Name.Derive--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
src/Data/Express/Utils/Typeable.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Data.Express.Utils.Typeable--- Copyright   : (c) 2016-2020 Rudy Matela+-- Copyright   : (c) 2016-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
test/Test.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Test--- Copyright   : (c) 2019-2020 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
test/Test/ListableExpr.hs view
@@ -1,6 +1,6 @@ -- | -- Module      : Test.ListableExpr--- Copyright   : (c) 2019 Rudy Matela+-- Copyright   : (c) 2019-2021 Rudy Matela -- License     : 3-Clause BSD  (see the file LICENSE) -- Maintainer  : Rudy Matela <rudy@matela.com.br> --
test/canon.hs view
@@ -1,12 +1,12 @@--- Copyright (c) 2017-2020 Rudy Matela.+-- Copyright (c) 2017-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test  main :: IO ()-main = mainTest tests 5040+main  =  mainTest tests 5040  tests :: Int -> [Bool]-tests n =+tests n  =   [ True    , canonicalize (xx -+- yy)@@ -102,19 +102,22 @@                     in length (nub (sort es)) == length es   , holds n $ \e -> length (canonicalVariations e)                  == product (map (bell . snd) . counts $ holes e)++  , holds n $ \e -> all isHole (vars e) ==> head (canonicalVariations e) == mostGeneralCanonicalVariation e+  , holds n $ \e -> all isHole (vars e) ==> last (canonicalVariations e) == mostSpecificCanonicalVariation e   ]  -- O(1) bell number implementation -- only works up to 8 -- but this is enough for testing. bell :: Int -> Int-bell 0 = 1-bell 1 = 1-bell 2 = 2-bell 3 = 5-bell 4 = 15-bell 5 = 52-bell 6 = 203-bell 7 = 877-bell 8 = 4140-bell _ = error "bell: argument > 8, implement me!"+bell 0  =  1+bell 1  =  1+bell 2  =  2+bell 3  =  5+bell 4  =  15+bell 5  =  52+bell 6  =  203+bell 7  =  877+bell 8  =  4140+bell _  =  error "bell: argument > 8, implement me!"
test/core.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test @@ -72,6 +72,11 @@   , isIllTyped (zero :$ one) == True   , isWellTyped (abs' zero) == True   , isWellTyped (zero :$ one) == False++  , isFun (value "abs" (abs :: Int -> Int)) == True+  , isFun (val (1::Int)) == False+  , isFun (value "const" (const :: Bool -> Bool -> Bool) :$ val False) == True+  , holds n $ \e -> (arity e /= 0) == isFun e    -- eq instance   , xx -+- yy == xx -+- yy
test/express-derive.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE DeriveDataTypeable #-}
test/express.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). {-# LANGUAGE CPP #-} import Test
test/fixtures.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2017-2020 Rudy Matela.+-- Copyright (c) 2017-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test @@ -170,4 +170,8 @@   , evl (unit bee) == "b"   , evl (bee -:- unit cee) == "bc"   , evl (bee -:- cee -:- unit dee) == "bcd"++  -- if --+  , evl (if' false zero one) == (1 :: Int)+  , evl (if' true two three) == (2 :: Int)   ]
test/fold.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test 
test/hole.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test @@ -27,4 +27,18 @@   , [pp, qq, rr, pp'] `isPrefixOf` listVars "p" (undefined :: Bool)   , [xx, yy, zz, xx'] `isPrefixOf` listVarsAsTypeOf "x" zero   , [pp, qq, rr, pp'] `isPrefixOf` listVarsAsTypeOf "p" false++  -- fill unit tests+  , fill (i_ -+- i_) [xx, yy] == xx -+- yy+  , fill (i_ -+- i_) [xx, xx] == xx -+- xx+  , fill (i_ -+- i_) [one, one -+- one] == one -+- (one -+- one)++  -- silent behaviours of fill+  , fill (i_ -+- i_ -+- i_) [xx, yy] == xx -+- yy -+- i_+  , fill (i_) [xx, yy] == xx+  , fill (i_ -+- i_ -+- i_) [xx, val 'c', yy] == xx -+- i_ -+- i_++  -- fill properties+  , holds n $ \(IntE e) -> fill (zero -+- i_ -+- two) [e] == zero -+- e -+- two+  , holds n $ \(IntE e1, IntE e2) -> fill (i_ -+- one -+- i_) [e1, e2] == e1 -+- one -+- e2   ]
test/instances.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2017-2020 Rudy Matela.+-- Copyright (c) 2017-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). {-# LANGUAGE NoMonomorphismRestriction #-} -- ACK! import Test
test/listable.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2017-2020 Rudy Matela.+-- Copyright (c) 2017-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test 
test/main.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test 
test/map.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test import Test.LeanCheck.Function
test/match.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test 
test/name-derive.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). {-# LANGUAGE TemplateHaskell #-} 
test/name.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2017-2020 Rudy Matela.+-- Copyright (c) 2017-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test 
test/ord.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2019-2020 Rudy Matela.+-- Copyright (c) 2019-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test 
test/sdist view
@@ -2,7 +2,7 @@ # # test/sdist: tests the package generated by "cabal sdist". #-# Copyright (c) 2015-2020 Rudy Matela.+# Copyright (c) 2015-2021 Rudy Matela. # Distributed under the 3-Clause BSD licence.  set -xe
test/show.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2017-2020 Rudy Matela.+-- Copyright (c) 2017-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test @@ -37,7 +37,6 @@   , show (value "`compare`" (compare :: Int->Int->Ordering) :$ one :$ two) == "1 `compare` 2 :: Ordering"    , holds n $ show . mapVars (\(Value ('_':s) d) -> Value (if null s then "_" else s) d) === show---, holds n $ show . mapConsts (\(Value s d) -> Value ('_':s) d) === show -- TODO:    , show emptyString == "\"\" :: [Char]"   , show (space -:- emptyString) == "\" \" :: [Char]"@@ -74,6 +73,23 @@   , show (ffE -$- minusOne) == "f $ (-1) :: Int"    , holds n $ \e -> showExpr e `isPrefixOf` show e++  , show (if' pp xx yy)             == "(if p then x else y) :: Int"+  , show (if' false zero one)       == "(if False then 0 else 1) :: Int"+  , show (if' true two three)       == "(if True then 2 else 3) :: Int"+  , show (if' pp false true)        == "(if p then False else True) :: Bool"+  , show (not' (if' pp false true)) == "not (if p then False else True) :: Bool"+  , show (if' pp xx yy -*- zz)      == "(if p then x else y) * z :: Int"+  , show (zz -*- if' pp xx yy)      == "z * (if p then x else y) :: Int"+  , show (if' pp false true -||- if' qq true false)+    == "(if p then False else True) || (if q then True else False) :: Bool"+  , show (if' (null' xxs) zero (head' xxs -+- value "sum" (sum :: [Int] -> Int) :$ tail' xxs))+    == "(if null xs then 0 else head xs + sum (tail xs)) :: Int"++  , showExpr (if' pp xx yy)             == "if p then x else y"+  , showExpr (if' false zero one)       == "if False then 0 else 1"+  , showExpr (if' true two three)       == "if True then 2 else 3"+  , showExpr (if' pp false true)        == "if p then False else True"    -- showing holes --   , show (hole (undefined :: Int -> Int) :$ one)              == "_ 1 :: Int"
test/utils.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2017-2020 Rudy Matela.+-- Copyright (c) 2017-2021 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Test