Copyright | (c) 2021-2024 Rudy Matela |
---|---|
License | 3-Clause BSD (see the file LICENSE) |
Maintainer | Rudy Matela <rudy@matela.com.br> |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
A library for Conjuring function implementations from tests or partial definitions. (a.k.a.: functional inductive programming)
This is currently an experimental tool in its early stages, don't expect much from its current version. It is just a piece of curiosity in its current state.
Step 1: declare your partial function
square :: Int -> Int square 0 = 0 square 1 = 1 square 2 = 4
Step 2: declare a list with the potential building blocks:
primitives :: [Prim] primitives = [ pr (0::Int) , pr (1::Int) , prim "+" ((+) :: Int -> Int -> Int) , prim "*" ((*) :: Int -> Int -> Int) ]
Step 3: call conjure and see your generated function:
> conjure "square" square primitives square :: Int -> Int -- testing 3 combinations of argument values -- pruning with 14/25 rules -- looking through 3 candidates of size 1 -- looking through 4 candidates of size 2 -- looking through 9 candidates of size 3 square x = x * x
Synopsis
- conjure :: Conjurable f => String -> f -> [Prim] -> IO ()
- type Prim = (Expr, Reification)
- pr :: (Conjurable a, Show a) => a -> Prim
- prim :: Conjurable a => String -> a -> Prim
- prif :: Conjurable a => a -> Prim
- primOrdCaseFor :: Conjurable a => a -> Prim
- conjureWithMaxSize :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()
- conjureWith :: Conjurable f => Args -> String -> f -> [Prim] -> IO ()
- data Args = Args {
- maxTests :: Int
- maxSize :: Int
- maxEvalRecursions :: Int
- maxEquationSize :: Int
- maxSearchTests :: Int
- maxDeconstructionSize :: Int
- carryOn :: Bool
- showTheory :: Bool
- usePatterns :: Bool
- rewriting :: Bool
- requireDescent :: Bool
- adHocRedundancy :: Bool
- copyBindings :: Bool
- atomicNumbers :: Bool
- uniqueCandidates :: Bool
- args :: Args
- data Expr
- val :: (Typeable a, Show a) => a -> Expr
- value :: Typeable a => String -> a -> Expr
- conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Prim] -> IO ()
- conjureFromSpecWith :: Conjurable f => Args -> String -> (f -> Bool) -> [Prim] -> IO ()
- class (Typeable a, Name a) => Conjurable a where
- conjureEquality :: a -> Maybe Expr
- conjureTiers :: a -> Maybe [[Expr]]
- conjureSubTypes :: a -> Reification
- conjureCases :: a -> [Expr]
- conjureSize :: a -> Int
- conjureExpress :: a -> Expr -> Expr
- reifyExpress :: (Express a, Show a) => a -> Expr -> Expr
- reifyEquality :: (Eq a, Typeable a) => a -> Maybe Expr
- reifyTiers :: (Listable a, Show a, Typeable a) => a -> Maybe [[Expr]]
- conjureType :: Conjurable a => a -> Reification
- class Name a where
- class (Show a, Typeable a) => Express a where
- deriveConjurable :: Name -> DecsQ
- deriveConjurableIfNeeded :: Name -> DecsQ
- deriveConjurableCascading :: Name -> DecsQ
- conjpure :: Conjurable f => String -> f -> [Prim] -> ([[Defn]], [[Defn]], [Expr], Thy)
- conjpureWith :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], [[Defn]], [Expr], Thy)
- data A
- data B
- data C
- data D
- data E
- data F
Basic use
conjure :: Conjurable f => String -> f -> [Prim] -> IO () Source #
Conjures an implementation of a partially defined function.
Takes a String
with the name of a function,
a partially-defined function from a conjurable type,
and a list of building blocks encoded as Expr
s.
For example, given:
square :: Int -> Int square 0 = 0 square 1 = 1 square 2 = 4 primitives :: [Prim] primitives = [ pr (0::Int) , pr (1::Int) , prim "+" ((+) :: Int -> Int -> Int) , prim "*" ((*) :: Int -> Int -> Int) ]
The conjure function does the following:
> conjure "square" square primitives square :: Int -> Int -- pruning with 14/25 rules -- testing 3 combinations of argument values -- looking through 3 candidates of size 1 -- looking through 3 candidates of size 2 -- looking through 5 candidates of size 3 square x = x * x
type Prim = (Expr, Reification) Source #
A primtive expression (paired with instance reification).
prif :: Conjurable a => a -> Prim Source #
Provides an if condition bound to the given return type.
primOrdCaseFor :: Conjurable a => a -> Prim Source #
Provides a case condition bound to the given return type.
Advanced use
conjureWithMaxSize :: Conjurable f => Int -> String -> f -> [Prim] -> IO () Source #
Like conjure
but allows setting the maximum size of considered expressions
instead of the default value of 12.
conjureWithMaxSize 10 "function" function [...]
conjureWith :: Conjurable f => Args -> String -> f -> [Prim] -> IO () Source #
Arguments to be passed to conjureWith
or conjpureWith
.
See args
for the defaults.
Args | |
|
Default arguments to conjure.
- 60 tests
- functions of up to 12 symbols
- maximum of one recursive call allowed in candidate bodies
- maximum evaluation of up to 60 recursions
- pruning with equations up to size 5
- search for defined applications for up to 100000 combinations
- require recursive calls to deconstruct arguments
- don't show the theory used in pruning
- do not make candidates unique module testing
Values of type Expr
represent objects or applications between objects.
Each object is encapsulated together with its type and string representation.
Values encoded in Expr
s are always monomorphic.
An Expr
can be constructed using:
val
, for values that areShow
instances;value
, for values that are notShow
instances, like functions;:$
, for applications betweenExpr
s.
> val False False :: Bool
> value "not" not :$ val False not False :: Bool
An Expr
can be evaluated using evaluate
, eval
or evl
.
> evl $ val (1 :: Int) :: Int 1
> evaluate $ val (1 :: Int) :: Maybe Bool Nothing
> eval 'a' (val 'b') 'b'
Show
ing a value of type Expr
will return a pretty-printed representation
of the expression together with its type.
> show (value "not" not :$ val False) "not False :: Bool"
Expr
is like Dynamic
but has support for applications and variables
(:$
, var
).
The var
underscore convention:
Functions that manipulate Expr
s usually follow the convention
where a value
whose String
representation starts with '_'
represents a var
iable.
Instances
Show Expr | Shows > show (value "not" not :$ val False) "not False :: Bool" |
Eq Expr | O(n). Does not evaluate values when comparing, but rather uses their representation as strings and their types. This instance works for ill-typed expressions. |
Ord Expr | O(n). Does not evaluate values when comparing, but rather uses their representation as strings and their types. This instance works for ill-typed expressions. Expressions come first
when they have smaller complexity ( |
value :: Typeable a => String -> a -> Expr #
O(1).
It takes a string representation of a value and a value, returning an
Expr
with that terminal value.
For instances of Show
, it is preferable to use val
.
> value "0" (0 :: Integer) 0 :: Integer
> value "'a'" 'a' 'a' :: Char
> value "True" True True :: Bool
> value "id" (id :: Int -> Int) id :: Int -> Int
> value "(+)" ((+) :: Int -> Int -> Int) (+) :: Int -> Int -> Int
> value "sort" (sort :: [Bool] -> [Bool]) sort :: [Bool] -> [Bool]
Conjuring from a specification
conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Prim] -> IO () Source #
Conjures an implementation from a function specification.
This function works like conjure
but instead of receiving a partial definition
it receives a boolean filter / property about the function.
For example, given:
squareSpec :: (Int -> Int) -> Bool squareSpec square = square 0 == 0 && square 1 == 1 && square 2 == 4
Then:
> conjureFromSpec "square" squareSpec primitives square :: Int -> Int -- pruning with 14/25 rules -- looking through 3 candidates of size 1 -- looking through 4 candidates of size 2 -- looking through 9 candidates of size 3 square x = x * x
This allows users to specify QuickCheck-style properties, here is an example using LeanCheck:
import Test.LeanCheck (holds, exists) squarePropertySpec :: (Int -> Int) -> Bool squarePropertySpec square = and [ holds n $ \x -> square x >= x , holds n $ \x -> square x >= 0 , exists n $ \x -> square x > x ] where n = 60
conjureFromSpecWith :: Conjurable f => Args -> String -> (f -> Bool) -> [Prim] -> IO () Source #
Like conjureFromSpec
but allows setting options through Args
/args
.
conjureFromSpecWith args{maxSize = 11} "function" spec [...]
When using custom types
class (Typeable a, Name a) => Conjurable a where Source #
Class of Conjurable
types.
Functions are Conjurable
if all their arguments are Conjurable
, Listable
and Show
able.
For atomic types that are Listable
,
instances are defined as:
instance Conjurable Atomic where conjureTiers = reifyTiers
For atomic types that are both Listable
and Eq
,
instances are defined as:
instance Conjurable Atomic where conjureTiers = reifyTiers conjureEquality = reifyEquality
For types with subtypes, instances are defined as:
instance Conjurable Composite where conjureTiers = reifyTiers conjureEquality = reifyEquality conjureSubTypes x = conjureType y . conjureType z . conjureType w where (Composite ... y ... z ... w ...) = x
Above x
, y
, z
and w
are just proxies.
The Proxy
type was avoided for backwards compatibility.
Please see the source code of Conjure.Conjurable for more examples.
(cf. reifyTiers
, reifyEquality
, conjureType
)
conjureEquality :: a -> Maybe Expr Source #
Returns Just
the ==
function encoded as an Expr
when available
or Nothing
otherwise.
Use reifyEquality
when defining this.
conjureTiers :: a -> Maybe [[Expr]] Source #
Returns Just
tiers
of values encoded as Expr
s when possible
or Nothing
otherwise.
Use reifyTiers
when defining this.
conjureSubTypes :: a -> Reification Source #
conjureCases :: a -> [Expr] Source #
Returns a top-level case breakdown.
conjureSize :: a -> Int Source #
Returns the (recursive) size of the given value.
conjureExpress :: a -> Expr -> Expr Source #
Returns a function that deeply reencodes an expression when possible.
(id
when not available.)
Use reifyExpress
when defining this.
Instances
reifyExpress :: (Express a, Show a) => a -> Expr -> Expr Source #
Reifies the expr
function in a Conjurable
type instance.
This is to be used
in the definition of conjureExpress
of Conjurable
typeclass instances.
instance ... => Conjurable <Type> where ... conjureExpress = reifyExpress ...
reifyEquality :: (Eq a, Typeable a) => a -> Maybe Expr Source #
Reifies equality ==
in a Conjurable
type instance.
This is to be used
in the definition of conjureEquality
of Conjurable
typeclass instances:
instance ... => Conjurable <Type> where ... conjureEquality = reifyEquality ...
reifyTiers :: (Listable a, Show a, Typeable a) => a -> Maybe [[Expr]] Source #
Reifies equality to be used in a conjurable type.
This is to be used
in the definition of conjureTiers
of Conjurable
typeclass instances:
instance ... => Conjurable <Type> where ... conjureTiers = reifyTiers ...
conjureType :: Conjurable a => a -> Reification Source #
To be used in the implementation of conjureSubTypes
.
instance ... => Conjurable <Type> where ... conjureSubTypes x = conjureType (field1 x) . conjureType (field2 x) . ... . conjureType (fieldN x) ...
If we were to come up with a variable name for the given type
what name
would it be?
An instance for a given type Ty
is simply given by:
instance Name Ty where name _ = "x"
Examples:
> name (undefined :: Int) "x"
> name (undefined :: Bool) "p"
> name (undefined :: [Int]) "xs"
This is then used to generate an infinite list of variable names
:
> names (undefined :: Int) ["x", "y", "z", "x'", "y'", "z'", "x''", "y''", "z''", ...]
> names (undefined :: Bool) ["p", "q", "r", "p'", "q'", "r'", "p''", "q''", "r''", ...]
> names (undefined :: [Int]) ["xs", "ys", "zs", "xs'", "ys'", "zs'", "xs''", "ys''", ...]
Nothing
O(1).
Returns a name for a variable of the given argument's type.
> name (undefined :: Int) "x"
> name (undefined :: [Bool]) "ps"
> name (undefined :: [Maybe Integer]) "mxs"
The default definition is:
name _ = "x"
Instances
Name Int16 | |
Defined in Data.Express.Name | |
Name Int32 | |
Defined in Data.Express.Name | |
Name Int64 | |
Defined in Data.Express.Name | |
Name Int8 | |
Defined in Data.Express.Name | |
Name GeneralCategory | |
Defined in Data.Express.Name name :: GeneralCategory -> String # | |
Name Word16 | |
Defined in Data.Express.Name | |
Name Word32 | |
Defined in Data.Express.Name | |
Name Word64 | |
Defined in Data.Express.Name | |
Name Word8 | |
Defined in Data.Express.Name | |
Name Ordering | name (undefined :: Ordering) = "o" names (undefined :: Ordering) = ["o", "p", "q", "o'", ...] |
Defined in Data.Express.Name | |
Name A Source # | |
Defined in Conjure.Conjurable | |
Name B Source # | |
Defined in Conjure.Conjurable | |
Name C Source # | |
Defined in Conjure.Conjurable | |
Name D Source # | |
Defined in Conjure.Conjurable | |
Name E Source # | |
Defined in Conjure.Conjurable | |
Name F Source # | |
Defined in Conjure.Conjurable | |
Name Integer | name (undefined :: Integer) = "x" names (undefined :: Integer) = ["x", "y", "z", "x'", ...] |
Defined in Data.Express.Name | |
Name () | name (undefined :: ()) = "u" names (undefined :: ()) = ["u", "v", "w", "u'", "v'", ...] |
Defined in Data.Express.Name | |
Name Bool | name (undefined :: Bool) = "p" names (undefined :: Bool) = ["p", "q", "r", "p'", "q'", ...] |
Defined in Data.Express.Name | |
Name Char | name (undefined :: Char) = "c" names (undefined :: Char) = ["c", "d", "e", "c'", "d'", ...] |
Defined in Data.Express.Name | |
Name Double | name (undefined :: Double) = "x" names (undefined :: Double) = ["x", "y", "z", "x'", ...] |
Defined in Data.Express.Name | |
Name Float | name (undefined :: Float) = "x" names (undefined :: Float) = ["x", "y", "z", "x'", ...] |
Defined in Data.Express.Name | |
Name Int | name (undefined :: Int) = "x" names (undefined :: Int) = ["x", "y", "z", "x'", "y'", ...] |
Defined in Data.Express.Name | |
Name Word | |
Defined in Data.Express.Name | |
Name (Complex a) | name (undefined :: Complex) = "x" names (undefined :: Complex) = ["x", "y", "z", "x'", ...] |
Defined in Data.Express.Name | |
Name (Ratio a) | name (undefined :: Rational) = "q" names (undefined :: Rational) = ["q", "r", "s", "q'", ...] |
Defined in Data.Express.Name | |
Name a => Name (Maybe a) | names (undefined :: Maybe Int) = ["mx", "mx1", "mx2", ...] nemes (undefined :: Maybe Bool) = ["mp", "mp1", "mp2", ...] |
Defined in Data.Express.Name | |
Name a => Name [a] | names (undefined :: [Int]) = ["xs", "ys", "zs", "xs'", ...] names (undefined :: [Bool]) = ["ps", "qs", "rs", "ps'", ...] |
Defined in Data.Express.Name | |
(Name a, Name b) => Name (Either a b) | names (undefined :: Either Int Int) = ["exy", "exy1", ...] names (undefined :: Either Int Bool) = ["exp", "exp1", ...] |
Defined in Data.Express.Name | |
(Name a, Name b) => Name (a, b) | names (undefined :: (Int,Int)) = ["xy", "zw", "xy'", ...] names (undefined :: (Bool,Bool)) = ["pq", "rs", "pq'", ...] |
Defined in Data.Express.Name | |
Name (a -> b) | names (undefined :: ()->()) = ["f", "g", "h", "f'", ...] names (undefined :: Int->Int) = ["f", "g", "h", ...] |
Defined in Data.Express.Name | |
(Name a, Name b, Name c) => Name (a, b, c) | names (undefined :: (Int,Int,Int)) = ["xyz","uvw", ...] names (undefined :: (Int,Bool,Char)) = ["xpc", "xpc1", ...] |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d) => Name (a, b, c, d) | names (undefined :: ((),(),(),())) = ["uuuu", "uuuu1", ...] names (undefined :: (Int,Int,Int,Int)) = ["xxxx", ...] |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e) => Name (a, b, c, d, e) | |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e, Name f) => Name (a, b, c, d, e, f) | |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e, Name f, Name g) => Name (a, b, c, d, e, f, g) | |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e, Name f, Name g, Name h) => Name (a, b, c, d, e, f, g, h) | |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e, Name f, Name g, Name h, Name i) => Name (a, b, c, d, e, f, g, h, i) | |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e, Name f, Name g, Name h, Name i, Name j) => Name (a, b, c, d, e, f, g, h, i, j) | |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e, Name f, Name g, Name h, Name i, Name j, Name k) => Name (a, b, c, d, e, f, g, h, i, j, k) | |
Defined in Data.Express.Name | |
(Name a, Name b, Name c, Name d, Name e, Name f, Name g, Name h, Name i, Name j, Name k, Name l) => Name (a, b, c, d, e, f, g, h, i, j, k, l) | |
Defined in Data.Express.Name |
class (Show a, Typeable a) => Express a where #
Express
typeclass instances provide an expr
function
that allows values to be deeply encoded as applications of Expr
s.
expr False = val False expr (Just True) = value "Just" (Just :: Bool -> Maybe Bool) :$ val True
The function expr
can be contrasted with the function val
:
val
always encodes values as atomicValue
Expr
s -- shallow encoding.expr
ideally encodes expressions as applications (:$
) betweenValue
Expr
s -- deep encoding.
Depending on the situation, one or the other may be desirable.
Instances can be automatically derived using the TH function
deriveExpress
.
The following example shows a datatype and its instance:
data Stack a = Stack a (Stack a) | Empty
instance Express a => Express (Stack a) where expr s@(Stack x y) = value "Stack" (Stack ->>: s) :$ expr x :$ expr y expr s@Empty = value "Empty" (Empty -: s)
To declare expr
it may be useful to use auxiliary type binding operators:
-:
, ->:
, ->>:
, ->>>:
, ->>>>:
, ->>>>>:
, ...
For types with atomic values, just declare expr = val
Instances
deriveConjurable :: Name -> DecsQ Source #
Derives an Conjurable
instance for the given type Name
.
This function needs the TemplateHaskell
extension.
If -:
, ->:
, ->>:
, ->>>:
, ... are not in scope,
this will derive them as well.
For now,
this function only derives
conjureEquality
,
conjureTiers
and
conjureExpress
and does not derive
conjureSubTypes
,
conjureArgumentCases
and
conjureSize
.
These will be added in future versions.
If you plan to use features that depend on these functionalities,
please define your instances manually.
deriveConjurableIfNeeded :: Name -> DecsQ Source #
Same as deriveConjurable
but does not warn when instance already exists
(deriveConjurable
is preferable).
For now,
this function only derives
conjureEquality
,
conjureTiers
and
conjureExpress
and does not derive
conjureSubTypes
,
conjureArgumentCases
and
conjureSize
.
These will be added in future versions.
If you plan to use features that depend on these functionalities,
please define your instances manually.
deriveConjurableCascading :: Name -> DecsQ Source #
Derives a Conjurable
instance for a given type Name
cascading derivation of type arguments as well.
For now,
this function only derives
conjureEquality
,
conjureTiers
and
conjureExpress
and does not derive
conjureSubTypes
,
conjureArgumentCases
and
conjureSize
.
These will be added in future versions.
If you plan to use features that depend on these functionalities,
please define your instances manually.
Pure interfaces
conjpure :: Conjurable f => String -> f -> [Prim] -> ([[Defn]], [[Defn]], [Expr], Thy) Source #
Like conjure
but in the pure world.
Returns a quadruple with:
- tiers of implementations
- tiers of candidates
- a list of tests
- the underlying theory
conjpureWith :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], [[Defn]], [Expr], Thy) Source #
Helper test types
Generic type A
.
Can be used to test polymorphic functions with a type variable
such as take
or sort
:
take :: Int -> [a] -> [a] sort :: Ord a => [a] -> [a]
by binding them to the following types:
take :: Int -> [A] -> [A] sort :: [A] -> [A]
This type is homomorphic to Nat6
, B
, C
, D
, E
and F
.
It is instance to several typeclasses so that it can be used to test functions with type contexts.
Instances
Bounded A | |
Enum A | |
Ix A | |
Num A | |
Read A | |
Integral A | |
Real A | |
Defined in Test.LeanCheck.Utils.Types toRational :: A -> Rational # | |
Show A | |
Conjurable A Source # | |
Defined in Conjure.Conjurable conjureArgumentHoles :: A -> [Expr] Source # conjureEquality :: A -> Maybe Expr Source # conjureTiers :: A -> Maybe [[Expr]] Source # conjureSubTypes :: A -> Reification Source # conjureIf :: A -> Expr Source # conjureCases :: A -> [Expr] Source # conjureArgumentCases :: A -> [[Expr]] Source # conjureSize :: A -> Int Source # conjureExpress :: A -> Expr -> Expr Source # conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe A Source # | |
Express A Source # | |
Defined in Conjure.Expr | |
Name A Source # | |
Defined in Conjure.Conjurable | |
Eq A | |
Ord A | |
Listable A | |
Generic type B
.
Can be used to test polymorphic functions with two type variables
such as map
or foldr
:
map :: (a -> b) -> [a] -> [b] foldr :: (a -> b -> b) -> b -> [a] -> b
by binding them to the following types:
map :: (A -> B) -> [A] -> [B] foldr :: (A -> B -> B) -> B -> [A] -> B
Instances
Bounded B | |
Enum B | |
Ix B | |
Num B | |
Read B | |
Integral B | |
Real B | |
Defined in Test.LeanCheck.Utils.Types toRational :: B -> Rational # | |
Show B | |
Conjurable B Source # | |
Defined in Conjure.Conjurable conjureArgumentHoles :: B -> [Expr] Source # conjureEquality :: B -> Maybe Expr Source # conjureTiers :: B -> Maybe [[Expr]] Source # conjureSubTypes :: B -> Reification Source # conjureIf :: B -> Expr Source # conjureCases :: B -> [Expr] Source # conjureArgumentCases :: B -> [[Expr]] Source # conjureSize :: B -> Int Source # conjureExpress :: B -> Expr -> Expr Source # conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe B Source # | |
Express B Source # | |
Defined in Conjure.Expr | |
Name B Source # | |
Defined in Conjure.Conjurable | |
Eq B | |
Ord B | |
Listable B | |
Generic type C
.
Can be used to test polymorphic functions with three type variables
such as uncurry
or zipWith
:
uncurry :: (a -> b -> c) -> (a, b) -> c zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
by binding them to the following types:
uncurry :: (A -> B -> C) -> (A, B) -> C zipWith :: (A -> B -> C) -> [A] -> [B] -> [C]
Instances
Bounded C | |
Enum C | |
Ix C | |
Num C | |
Read C | |
Integral C | |
Real C | |
Defined in Test.LeanCheck.Utils.Types toRational :: C -> Rational # | |
Show C | |
Conjurable C Source # | |
Defined in Conjure.Conjurable conjureArgumentHoles :: C -> [Expr] Source # conjureEquality :: C -> Maybe Expr Source # conjureTiers :: C -> Maybe [[Expr]] Source # conjureSubTypes :: C -> Reification Source # conjureIf :: C -> Expr Source # conjureCases :: C -> [Expr] Source # conjureArgumentCases :: C -> [[Expr]] Source # conjureSize :: C -> Int Source # conjureExpress :: C -> Expr -> Expr Source # conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe C Source # | |
Express C Source # | |
Defined in Conjure.Expr | |
Name C Source # | |
Defined in Conjure.Conjurable | |
Eq C | |
Ord C | |
Listable C | |
Generic type D
.
Can be used to test polymorphic functions with four type variables.
Instances
Bounded D | |
Enum D | |
Ix D | |
Num D | |
Read D | |
Integral D | |
Real D | |
Defined in Test.LeanCheck.Utils.Types toRational :: D -> Rational # | |
Show D | |
Conjurable D Source # | |
Defined in Conjure.Conjurable conjureArgumentHoles :: D -> [Expr] Source # conjureEquality :: D -> Maybe Expr Source # conjureTiers :: D -> Maybe [[Expr]] Source # conjureSubTypes :: D -> Reification Source # conjureIf :: D -> Expr Source # conjureCases :: D -> [Expr] Source # conjureArgumentCases :: D -> [[Expr]] Source # conjureSize :: D -> Int Source # conjureExpress :: D -> Expr -> Expr Source # conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe D Source # | |
Express D Source # | |
Defined in Conjure.Expr | |
Name D Source # | |
Defined in Conjure.Conjurable | |
Eq D | |
Ord D | |
Listable D | |
Generic type E
.
Can be used to test polymorphic functions with five type variables.
Instances
Bounded E | |
Enum E | |
Ix E | |
Num E | |
Read E | |
Integral E | |
Real E | |
Defined in Test.LeanCheck.Utils.Types toRational :: E -> Rational # | |
Show E | |
Conjurable E Source # | |
Defined in Conjure.Conjurable conjureArgumentHoles :: E -> [Expr] Source # conjureEquality :: E -> Maybe Expr Source # conjureTiers :: E -> Maybe [[Expr]] Source # conjureSubTypes :: E -> Reification Source # conjureIf :: E -> Expr Source # conjureCases :: E -> [Expr] Source # conjureArgumentCases :: E -> [[Expr]] Source # conjureSize :: E -> Int Source # conjureExpress :: E -> Expr -> Expr Source # conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe E Source # | |
Express E Source # | |
Defined in Conjure.Expr | |
Name E Source # | |
Defined in Conjure.Conjurable | |
Eq E | |
Ord E | |
Listable E | |
Generic type F
.
Can be used to test polymorphic functions with five type variables.
Instances
Bounded F | |
Enum F | |
Ix F | |
Num F | |
Read F | |
Integral F | |
Real F | |
Defined in Test.LeanCheck.Utils.Types toRational :: F -> Rational # | |
Show F | |
Conjurable F Source # | |
Defined in Conjure.Conjurable conjureArgumentHoles :: F -> [Expr] Source # conjureEquality :: F -> Maybe Expr Source # conjureTiers :: F -> Maybe [[Expr]] Source # conjureSubTypes :: F -> Reification Source # conjureIf :: F -> Expr Source # conjureCases :: F -> [Expr] Source # conjureArgumentCases :: F -> [[Expr]] Source # conjureSize :: F -> Int Source # conjureExpress :: F -> Expr -> Expr Source # conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe F Source # | |
Express F Source # | |
Defined in Conjure.Expr | |
Name F Source # | |
Defined in Conjure.Conjurable | |
Eq F | |
Ord F | |
Listable F | |