speculate 0.4.2 → 0.4.4
raw patch · 18 files changed
+211/−148 lines, 18 filesdep ~express
Dependency ranges changed: express
Files
- .travis.yml +13/−9
- Makefile +2/−2
- README.md +132/−5
- bench/runtime-zero +32/−33
- eg/tauts.hs +2/−2
- mk/depend.mk +0/−2
- mk/ghcdeps +2/−1
- mk/haddock-i +1/−1
- mk/haskell.mk +1/−1
- mk/install-on +4/−1
- speculate.cabal +3/−3
- src/Test/Speculate/Engine.hs +14/−20
- src/Test/Speculate/Expr/Core.hs +0/−14
- stack.yaml +2/−2
- test/engine.hs +0/−5
- test/model/list-c-s4.out +1/−23
- test/model/list-c.out +1/−23
- test/sdist +1/−1
.travis.yml view
@@ -1,6 +1,6 @@ # .travis.yml file for Speculate #-# 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> @@ -34,7 +34,7 @@ - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' - stack config set system-ghc --global true - stack --version-- cabal install leancheck express cmdargs || cabal install leancheck express cmdargs --lib+- cabal install leancheck express cmdargs || cabal v1-install leancheck express cmdargs script: - make && make test@@ -45,17 +45,21 @@ matrix: allow_failures:- - ghc: 'head'+ - env: GHCVER=head CABALVER=head STACKVER=nightly-2021-04-06+ - env: GHCVER=9.0.1 CABALVER=head STACKVER=nightly-2021-04-06 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.1 CABALVER=3.2 STACKVER=nightly-2020-03-28- addons: {apt: {packages: [ghc-8.10.1, cabal-install-3.2], sources: hvr-ghc}}+ 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}}
Makefile view
@@ -104,8 +104,8 @@ cabal clean && cabal-ghc-7.8 configure && cabal-ghc-7.8 test cabal clean && cabal test -prepare-test:- cabal --ignore-sandbox install regex-tdfa cmdargs leancheck algebraic-graphs pretty-compact+prepare:+ cabal v1-install cmdargs leancheck express regex-tdfa algebraic-graphs pretty-compact prepare-legacy-test: \ prepare-legacy-test-8.2 \
README.md view
@@ -12,7 +12,7 @@ Give Speculate a bunch of Haskell functions and it will discover laws like: * equations, such as `id x == x`;- * inequalities, such as `0 <= x * x`;+ * relations of order, such as `0 <= x * x`; * conditional equations, such as `x <= 0 ==> x + abs x == 0`. Speculate is similar to, and inspired by, [QuickSpec].@@ -91,7 +91,115 @@ For more examples, see the [eg](eg) folder. +(One can use the [TypeApplications] to simplify the above examples:+`((+) @ Int)` instead of `((+) :: Int -> Int -> Int))`.+I have chosen to keep the example [Haskell 98] compliant.) ++Supported types+---------------++Speculate works for virtually any type.+However,+if you would like to produce equations,+comparisons and variables of any given type+this type must be respectively+an instance of the [`Eq`], [`Ord`], [`Listable`] and [`Name`] typeclasses.++By default,+Speculate will produce equations, comparison and variables+to [a few types](https://github.com/rudymatela/speculate/blob/master/src/Test/Speculate/Expr/Instance.hs#L110-L151)+in the [Haskell 2010 Language Report].+If you would like expand that to more types,+you need to pass reified instances to Speculate explicitly by+using [`reifyInstances`] on [`instances =`] of [`speculate`]'s [`args`] like so:++ main = speculate args+ { instances = [ reifyInstances (undefined :: <Type1>)+ , reifyInstances (undefined :: <Type2>)+ , reifyInstances (undefined :: <Type3>)+ , ...+ ]+ , constants = ...+ , ...+ }++To use [`reifyInstances`],+your type must be an instance of+[`Eq`], [`Ord`], [`Listable`] and [`Name`].++* [`Eq`] is needed for equations between values of the type;++* [`Ord`] is needed for comparisons between values of the type;++* [`Listable`] is needed for involving variables of the type.+ This is needed in order for Speculate to be able+ to generate values of your type to replace any variables.+ [LeanCheck] comes with [`Listable`] instances+ for virtually all types in the [Haskell 2010 Language Report].++* [`Name`] is needed for cosmetic puposes:+ if there are any variables of your type,+ [`Name`] allows you to tell Speculate how to call your variables.+ For example, if you have an `User` type, you can define your name instance as:++ instance Name (User) where+ name u = "usr"++ This way, variables of your `User` type will be called:+ `usr`, `usr1`, `usr2`, `usr3`, etc.++It is also fine to have only one, two or three of the above instances.+In that case, instead of [`reifyInstances`]+you can use [`reifyEq`], [`reifyOrd`], [`reifyListable`] and [`reifyName`] accordingly.+If you do not provide a [`Name`] implementation,+your variables will default to being `x`, `y` and `z`.+This may cause confusion as you involve more and more types,+compare the following two identical equations:++ [x,y] `areOwnedBy` z == z `owns` x && z `owns` y+ [tckt,tckt1] `areOwnedBy` user == usr `owns` tckt && user `owns tckt1`++The second is clearer.+So, I recomment you add a [`Name`] instance.+It is simple enough.++You also have to do this for any user defined types you are using+or even for newtypes.++Speculate comes with a few examples illustrating the use of [`reifyInstances`]:+on the [eg](eg) folder:+[eg/algebraic-graphs.hs](eg/algebraic-graphs.hs),+[eg/binarytree0.hs](eg/binarytree0.hs),+[eg/binarytree.hs](eg/binarytree.hs),+[eg/colour.hs](eg/colour.hs),+[eg/digraphs.hs](eg/digraphs.hs),+[eg/fun.hs](eg/fun.hs),+[eg/monad.hs](eg/monad.hs),+[eg/pretty-compact.hs](eg/pretty-compact.hs),+[eg/pretty.hs](eg/pretty.hs),+[eg/regexes.hs](eg/regexes.hs),+[eg/sets.hs](eg/sets.hs),+[eg/speculate-reason.hs](eg/speculate-reason.hs),+[eg/string.hs](eg/string.hs),+[eg/tauts.hs](eg/tauts.hs),+[eg/tuples.hs](eg/tuples.hs),+[eg/zip.hs](eg/zip.hs).++Not having the reified instances for a given type will cause the following warnings to be printed:++ Warning: no Listable instance for <YourTypeHere>, variables of this type will not be considered+ Warning: no Listable instance for <YourTypeHere>, variables of this type will not be considered+ Warning: no Eq instance for <YourTypeHere>, equations of this type will not be considered+ Warning: no Eq instance for <YourTypeHere>, equations of this type will not be considered+ Warning: no Ord instance for <YourTypeHere>, inequations of this type will not be considered+ Warning: no Ord instance for <YourTypeHere>, inequations of this type will not be considered++You can silence the above warnings by following the instructions above.+However, it may be the case that you don't want variables, equations or comparisons for a given type.+If that is so, you can ignore these warnings.++ Similarities and Differences to QuickSpec ----------------------------------------- @@ -101,7 +209,7 @@ * Speculate tests enumeratively using [LeanCheck], QuickSpec tests randomly using [QuickCheck];-* Speculate is able to report inequalities directly;+* Speculate is able to report comparisons directly; * QuickSpec allows polymorphism, Speculate does not; * For most examples, Speculate runs slower than QuickSpec 2@@ -129,14 +237,33 @@ [PhD Thesis (2017)]: https://matela.com.br/paper/rudy-phd-thesis-2017.pdf -[`speculate`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:speculate-[`args`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:args-[`constant`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:constant+[`speculate`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:speculate+[`constant`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:constant+[`args`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:args+[`Args`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#t:Args+[`instances =`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#t:Args +[`reifyInstances`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:reifyInstances+[`reifyEq`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:reifyEq+[`reifyOrd`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:reifyOrd+[`reifyEqOrd`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:reifyEqOrd+[`reifyListable`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:reifyListable+[`reifyName`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#v:reifyName++[`Eq`]: https://hackage.haskell.org/package/base/docs/Prelude.html#t:Eq+[`Ord`]: https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord+[`Listable`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#t:Listable+[`Name`]: https://hackage.haskell.org/package/speculate/docs/Test-Speculate.html#t:Name+ [`(+)`]: https://hackage.haskell.org/package/base/docs/Prelude.html#v:-43- [`abs`]: https://hackage.haskell.org/package/base/docs/Prelude.html#v:abs [`<=`]: https://hackage.haskell.org/package/base/docs/Prelude.html#v:-60--61- [`<`]: https://hackage.haskell.org/package/base/docs/Prelude.html#v:-60-++[Haskell 2010 Language Report]: https://www.haskell.org/onlinereport/haskell2010/+[Haskell 2010]: https://www.haskell.org/onlinereport/haskell2010/+[Haskell 98]: https://www.haskell.org/onlinereport/+[TypeApplications]: https://gitlab.haskell.org/ghc/ghc/-/wikis/type-application [speculate-logo]: https://github.com/rudymatela/speculate/raw/master/doc/speculate.svg?sanitize=true
bench/runtime-zero view
@@ -1,35 +1,34 @@-GHC 8.6.5-express-0.1.1-leancheck-0.9.1-arith 0.260-arith-c 0.603-arithficial 0.966-arith-negate-abs 1.846-binarytree 1.753-binarytree0 0.520-bool 1.983-bool-c 1.723-colour 2.130-digraphs 1.560-fun 1.190-insertsort 8.593-insertsort0 0.996-length 0.646-list 2.826-list-c 1.770-minus 0.603-minus-c 0.996-monad 0.690+GHC 8.10.4+express-0.1.4+leancheck-0.9.3+arith 0.233+arith-c 0.570+arithficial 0.860+arith-negate-abs 1.713+binarytree 1.633+binarytree0 0.483+bool 1.963+bool-c 1.730+colour 1.946+digraphs 1.460+fun 1.103+insertsort 7.613+insertsort0 0.913+length 0.460+list 2.586+list-c 1.596+minus 0.506+minus-c 0.883+monad 0.583 nord 0.010-oddeven 7.340-plus-abs 3.786-pretty 9.080-ratio 9.300-regexes 8.013-sets 7.696-speculate-reason 3.300-string 0.950-tauts 4.286-tuples 1.286+oddeven 6.673+plus-abs 3.543+pretty 8.953+ratio 8.093+sets 7.183+speculate-reason 3.016+string 0.856+tauts 4.073+tuples 1.200 unit 0.010-zip 2.463+zip 2.303
eg/tauts.hs view
@@ -4,11 +4,11 @@ import qualified Test.Speculate as S import Taut hiding (main) -deriveListable ''Prop deriveListable ''Name+deriveListable ''Prop -deriving instance Typeable Prop deriving instance Typeable Name+deriving instance Typeable Prop prop :: Prop prop = undefined
mk/depend.mk view
@@ -1077,8 +1077,6 @@ src/Test/Speculate/Expr/Core.hs \ src/Test/Speculate/Engine.hs \ src/Test/Speculate/CondReason.hs-src/Test/Speculate/Expr/Core: \- mk/toplibs src/Test/Speculate/Expr/Core.o: \ src/Test/Speculate/Utils/List.hs \ src/Test/Speculate/Expr/Core.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
speculate.cabal view
@@ -1,5 +1,5 @@ name: speculate-version: 0.4.2+version: 0.4.4 synopsis: discovery of properties about Haskell functions description: Speculate automatically discovers laws about Haskell functions.@@ -84,7 +84,7 @@ source-repository this type: git location: https://github.com/rudymatela/speculate- tag: v0.4.2+ tag: v0.4.4 library@@ -121,7 +121,7 @@ , Test.Speculate.Utils.Tuple build-depends: base >= 4 && < 5 , leancheck >= 0.9.3- , express >= 0.1.3+ , express >= 0.1.4 , cmdargs , containers hs-source-dirs: src
src/Test/Speculate/Engine.hs view
@@ -11,8 +11,6 @@ ( expansions , expansionsOfType , expansionsWith- , mostGeneral- , mostSpecific , theoryAndRepresentativesFromAtoms , representativesFromAtoms@@ -102,14 +100,6 @@ (h,c):_ -> expansions is n `concatMap` expansionsOfType h (take n (lookupNames is h)) e --- | List the most general assignment of holes in an expression-mostGeneral :: Expr -> Expr-mostGeneral = head . fastCanonicalVariations -- TODO: make this efficient---- | List the most specific assignment of holes in an expression-mostSpecific :: Expr -> Expr-mostSpecific = last . fastCanonicalVariations -- TODO: make this efficient- rehole :: Expr -> Expr rehole (e1 :$ e2) = rehole e1 :$ rehole e2 rehole e | isVar e = "" `varAsTypeOf` e@@ -133,6 +123,9 @@ -- > } theoryFromAtoms :: Int -> (Expr -> Expr -> Ordering) -> (Expr -> Bool) -> (Expr -> Expr -> Bool) -> [[Expr]] -> Thy theoryFromAtoms sz cmp keep (===) = fst . theoryAndRepresentativesFromAtoms sz cmp keep (===)+-- TODO: eliminate two arguments:+-- * cmp can default to use order of appearance+-- * keep can default to "const True" representativesFromAtoms :: Int -> (Expr -> Expr -> Ordering) -> (Expr -> Bool) -> (Expr -> Expr -> Bool) -> [[Expr]] -> [[Expr]] representativesFromAtoms sz cmp keep (===) = snd . theoryAndRepresentativesFromAtoms sz cmp keep (===)@@ -165,20 +158,21 @@ -- considers a schema consider :: (Expr -> Expr -> Bool) -> Int -> Expr -> (Thy,[[Expr]]) -> (Thy,[[Expr]]) consider (===) sz s (thy,sss)- | not (s === s) = (thy,sssWs) -- uncomparable type- | rehole (normalizeE thy (mostGeneral s)) `elem` ss = (thy,sss)+ | ns `elem` ss = (thy,sss)+ | not (ns === ns) = (thy,sssWs) -- uncomparable type | otherwise =- ( append thy $ equivalencesBetween (-===-) s s ++ eqs+ ( append thy $ equivalencesBetween (-===-) ns ns ++ eqs , if any (\(e1,e2) -> unrepeatedVars e1 && unrepeatedVars e2) eqs then sss else sssWs )- where- e1 -===- e2 = normalize thy e1 == normalize thy e2 || e1 === e2- ss = uptoT sz sss- sssWs = sss \/ wcons0 sz s- eqs = concatMap (equivalencesBetween (-===-) s) $ filter (s ===) ss- wcons0 :: Int -> a -> [[a]]- wcons0 n s = replicate (n-1) [] ++ [[s]]+ where+ ns = rehole $ normalizeE thy (fastMostGeneralVariation s)+ e1 -===- e2 = normalize thy e1 == normalize thy e2 || e1 === e2+ ss = uptoT sz sss+ sssWs = sss \/ wcons0 sz s+ eqs = concatMap (equivalencesBetween (-===-) s) $ filter (s ===) ss+ wcons0 :: Int -> a -> [[a]]+ wcons0 n s = replicate (n-1) [] ++ [[s]] distinctFromSchemas :: Instances -> Int -> Int -> Thy -> [Expr] -> [Expr] distinctFromSchemas ti nt nv thy = map C.rep . classesFromSchemas ti nt nv thy
src/Test/Speculate/Expr/Core.hs view
@@ -23,7 +23,6 @@ -- * Assigning , Binds- , fill -- * Matching , unify@@ -83,19 +82,6 @@ _ `isConstantNamed` _ = False type Binds = [(Expr,Expr)]---- | 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) unify :: Expr -> Expr -> Maybe Expr unify e1 e2 = (e1 //-) <$> unification e1 e2
stack.yaml view
@@ -1,8 +1,8 @@-resolver: lts-15.5 # or ghc-8.8.3+resolver: lts-17.9 # or ghc-8.10.4 packages: - . extra-deps: - leancheck-0.9.3-- express-0.1.3+- express-0.1.4
test/engine.hs view
@@ -14,11 +14,6 @@ tests :: Int -> [Bool] tests n = [ True- - , holds n $ \e -> mostGeneral e == head (fastCanonicalVariations e)- , holds n $ \e -> mostSpecific e == last (fastCanonicalVariations e)- , holds n $ \e -> allLater (\e1 e0 -> not (e0 `isInstanceOf` e1))- $ fastCanonicalVariations e , equivalencesBetween (===) (i_ -+- i_) (i_ -+- i_) == [ ( xx -+- yy, yy -+- xx ) ]
test/model/list-c-s4.out view
@@ -36,44 +36,26 @@ _:tail [] :: [Int] _ ++ tail _ :: [Int] _ ++ tail [] :: [Int]-[] ++ tail _ :: [Int]-[] ++ tail [] :: [Int] head _:_ :: [Int] [head _] :: [Int] head []:_ :: [Int] [head []] :: [Int] tail _ ++ _ :: [Int]-tail _ ++ [] :: [Int] tail [] ++ _ :: [Int]-tail [] ++ [] :: [Int] head (tail (tail (tail _))) :: Int head (tail (tail (tail []))) :: Int head (tail (_ ++ _)) :: Int head (_ ++ tail _) :: Int head (_ ++ tail []) :: Int-head ([] ++ tail _) :: Int-head ([] ++ tail []) :: Int-head (head _:_) :: Int-head [head _] :: Int-head (head []:_) :: Int-head [head []] :: Int head (tail _ ++ _) :: Int-head (tail _ ++ []) :: Int head (tail [] ++ _) :: Int-head (tail [] ++ []) :: Int tail (tail (tail (tail _))) :: [Int] tail (tail (tail (tail []))) :: [Int] tail (tail (_ ++ _)) :: [Int]-tail (_:tail _) :: [Int]-tail (_:tail []) :: [Int] tail (_ ++ tail _) :: [Int] tail (_ ++ tail []) :: [Int]-tail ([] ++ tail _) :: [Int]-tail ([] ++ tail []) :: [Int] tail (tail _ ++ _) :: [Int]-tail (tail _ ++ []) :: [Int] tail (tail [] ++ _) :: [Int]-tail (tail [] ++ []) :: [Int] _:tail (tail _) :: [Int] _:tail (tail []) :: [Int] _:_:_ :: [Int]@@ -84,8 +66,6 @@ _ ++ (_:_) :: [Int] _ ++ [_] :: [Int] _ ++ (_ ++ _) :: [Int]-[] ++ tail (tail _) :: [Int]-[] ++ tail (tail []) :: [Int] head _:tail _ :: [Int] head _:tail [] :: [Int] head []:tail _ :: [Int]@@ -99,9 +79,7 @@ head (tail []):_ :: [Int] [head (tail [])] :: [Int] tail (tail _) ++ _ :: [Int]-tail (tail _) ++ [] :: [Int] tail (tail []) ++ _ :: [Int]-tail (tail []) ++ [] :: [Int] x :: Int xs :: [Int]@@ -771,7 +749,7 @@ tail (tail []) ++ ys :: [Int] tail (tail []) ++ zs :: [Int] -Number of Eq schema classes: 90+Number of Eq schema classes: 68 Number of Eq 1-var classes: 68 Number of Eq 2-var classes: 191 Number of Eq 3-var classes: 406
test/model/list-c.out view
@@ -36,44 +36,26 @@ _:tail [] :: [Int] _ ++ tail _ :: [Int] _ ++ tail [] :: [Int]-[] ++ tail _ :: [Int]-[] ++ tail [] :: [Int] head _:_ :: [Int] [head _] :: [Int] head []:_ :: [Int] [head []] :: [Int] tail _ ++ _ :: [Int]-tail _ ++ [] :: [Int] tail [] ++ _ :: [Int]-tail [] ++ [] :: [Int] head (tail (tail (tail _))) :: Int head (tail (tail (tail []))) :: Int head (tail (_ ++ _)) :: Int head (_ ++ tail _) :: Int head (_ ++ tail []) :: Int-head ([] ++ tail _) :: Int-head ([] ++ tail []) :: Int-head (head _:_) :: Int-head [head _] :: Int-head (head []:_) :: Int-head [head []] :: Int head (tail _ ++ _) :: Int-head (tail _ ++ []) :: Int head (tail [] ++ _) :: Int-head (tail [] ++ []) :: Int tail (tail (tail (tail _))) :: [Int] tail (tail (tail (tail []))) :: [Int] tail (tail (_ ++ _)) :: [Int]-tail (_:tail _) :: [Int]-tail (_:tail []) :: [Int] tail (_ ++ tail _) :: [Int] tail (_ ++ tail []) :: [Int]-tail ([] ++ tail _) :: [Int]-tail ([] ++ tail []) :: [Int] tail (tail _ ++ _) :: [Int]-tail (tail _ ++ []) :: [Int] tail (tail [] ++ _) :: [Int]-tail (tail [] ++ []) :: [Int] _:tail (tail _) :: [Int] _:tail (tail []) :: [Int] _:_:_ :: [Int]@@ -84,8 +66,6 @@ _ ++ (_:_) :: [Int] _ ++ [_] :: [Int] _ ++ (_ ++ _) :: [Int]-[] ++ tail (tail _) :: [Int]-[] ++ tail (tail []) :: [Int] head _:tail _ :: [Int] head _:tail [] :: [Int] head []:tail _ :: [Int]@@ -99,9 +79,7 @@ head (tail []):_ :: [Int] [head (tail [])] :: [Int] tail (tail _) ++ _ :: [Int]-tail (tail _) ++ [] :: [Int] tail (tail []) ++ _ :: [Int]-tail (tail []) ++ [] :: [Int] x :: Int xs :: [Int]@@ -771,7 +749,7 @@ tail (tail []) ++ ys :: [Int] tail (tail []) ++ zs :: [Int] -Number of Eq schema classes: 90+Number of Eq schema classes: 68 Number of Eq 1-var classes: 68 Number of Eq 2-var classes: 191 Number of Eq 3-var classes: 406
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