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 +11/−5
- LICENSE +1/−1
- Makefile +24/−12
- README.md +5/−0
- bench/compare.hs +1/−1
- bench/pairs.hs +1/−1
- bench/tiers.hs +1/−1
- eg/u-extrapolate.hs +1/−1
- eg/u-speculate.hs +3/−3
- express.cabal +2/−2
- mk/depend.mk +2/−2
- mk/ghcdeps +2/−1
- mk/haddock-i +1/−1
- mk/haskell.mk +1/−1
- mk/install-on +4/−1
- src/Data/Express.hs +7/−2
- src/Data/Express/Basic.hs +1/−1
- src/Data/Express/Canon.hs +99/−16
- src/Data/Express/Core.hs +35/−20
- src/Data/Express/Express.hs +1/−1
- src/Data/Express/Express/Derive.hs +1/−1
- src/Data/Express/Fixtures.hs +57/−1
- src/Data/Express/Fold.hs +3/−3
- src/Data/Express/Hole.hs +46/−1
- src/Data/Express/Instances.hs +1/−1
- src/Data/Express/Map.hs +1/−1
- src/Data/Express/Match.hs +1/−1
- src/Data/Express/Name.hs +1/−1
- src/Data/Express/Name/Derive.hs +1/−1
- src/Data/Express/Utils/List.hs +1/−1
- src/Data/Express/Utils/String.hs +33/−33
- src/Data/Express/Utils/TH.hs +1/−1
- src/Data/Express/Utils/Typeable.hs +1/−1
- test/Test.hs +1/−1
- test/Test/ListableExpr.hs +1/−1
- test/canon.hs +16/−13
- test/core.hs +6/−1
- test/express-derive.hs +1/−1
- test/express.hs +1/−1
- test/fixtures.hs +5/−1
- test/fold.hs +1/−1
- test/hole.hs +15/−1
- test/instances.hs +1/−1
- test/listable.hs +1/−1
- test/main.hs +1/−1
- test/map.hs +1/−1
- test/match.hs +1/−1
- test/name-derive.hs +1/−1
- test/name.hs +1/−1
- test/ord.hs +1/−1
- test/sdist +1/−1
- test/show.hs +18/−2
- test/utils.hs +1/−1
.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