Copyright | (c) 2021 Rudy Matela |
---|---|
License | 3-Clause BSD (see the file LICENSE) |
Maintainer | Rudy Matela <rudy@matela.com.br> |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
This module is part of Conjure.
This defines the Conjurable
typeclass
and utilities involving it.
You are probably better off importing Conjure.
Synopsis
- type Reification1 = (Expr, Maybe Expr, Maybe [[Expr]], [String], Bool, Expr)
- type Reification = [Reification1] -> [Reification1]
- class (Typeable a, Name a) => Conjurable a where
- conjureArgumentHoles :: a -> [Expr]
- conjureEquality :: a -> Maybe Expr
- conjureTiers :: a -> Maybe [[Expr]]
- conjureSubTypes :: a -> Reification
- conjureIf :: a -> Expr
- conjureCases :: a -> [Expr]
- conjureArgumentCases :: a -> [[Expr]]
- conjureSize :: a -> Int
- conjureExpress :: a -> Expr -> Expr
- conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe a
- conjureType :: Conjurable a => a -> Reification
- reifyTiers :: (Listable a, Show a, Typeable a) => a -> Maybe [[Expr]]
- reifyEquality :: (Eq a, Typeable a) => a -> Maybe Expr
- reifyExpress :: (Express a, Show a) => a -> Expr -> Expr
- conjureApplication :: Conjurable f => String -> f -> Expr
- conjureVarApplication :: Conjurable f => String -> f -> Expr
- conjurePats :: Conjurable f => [Expr] -> String -> f -> [[[Expr]]]
- conjureHoles :: Conjurable f => f -> [Expr]
- conjureTiersFor :: Conjurable f => f -> Expr -> [[Expr]]
- conjureAreEqual :: Conjurable f => f -> Int -> Expr -> Expr -> Bool
- conjureMkEquation :: Conjurable f => f -> Expr -> Expr -> Expr
- data A
- data B
- data C
- data D
- data E
- data F
- conjureIsDeconstruction :: Conjurable f => f -> Int -> Expr -> Bool
- candidateDeconstructionsFrom :: Expr -> [Expr]
- candidateDeconstructionsFromHoled :: Expr -> [Expr]
- conjureIsUnbreakable :: Conjurable f => f -> Expr -> Bool
- conjureReification :: Conjurable a => a -> [Reification1]
- conjureReification1 :: Conjurable a => a -> Reification1
- conjureDynamicEq :: Conjurable f => f -> Dynamic
- conjureIsNumeric :: Conjurable f => f -> Expr -> Bool
- cevaluate :: Conjurable f => Int -> Defn -> Maybe f
- ceval :: Conjurable f => Int -> f -> Defn -> f
- cevl :: Conjurable f => Int -> Defn -> f
- class Name a where
- class (Show a, Typeable a) => Express a where
- conjureArgumentPats :: Conjurable f => [Expr] -> f -> [[[[Expr]]]]
- conjureMostGeneralCanonicalVariation :: Conjurable f => f -> Expr -> Expr
Documentation
type Reification1 = (Expr, Maybe Expr, Maybe [[Expr]], [String], Bool, Expr) Source #
Single reification of some functions over a type as Expr
s.
This is a sixtuple, in order:
type Reification = [Reification1] -> [Reification1] Source #
A reification over a collection of types.
Represented as a transformation of a list to a list.
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
)
conjureArgumentHoles :: a -> [Expr] Source #
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 #
conjureIf :: a -> Expr Source #
Returns an if-function encoded as an Expr
.
conjureCases :: a -> [Expr] Source #
Returns a top-level case breakdown.
conjureArgumentCases :: a -> [[Expr]] Source #
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.
conjureEvaluate :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe a Source #
Instances
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) ...
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 ...
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 ...
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 ...
conjureApplication :: Conjurable f => String -> f -> Expr Source #
Computes a complete application for the given function.
> conjureApplication "not" not not p :: Bool
> conjureApplication "+" ((+) :: Int -> Int -> Int) x + y :: Int
(cf. conjureVarApplication
)
conjureVarApplication :: Conjurable f => String -> f -> Expr Source #
Computes a complete application for a variable of the same type of the given function.
> conjureVarApplication "not" not not p :: Bool
> conjureVarApplication "+" ((+) :: Int -> Int -> Int) x + y :: Int
(cf. conjureApplication
)
conjurePats :: Conjurable f => [Expr] -> String -> f -> [[[Expr]]] Source #
Computes tiers of sets of patterns for the given function.
> conjurePats [zero] "f" (undefined :: Int -> Int) [[[f x :: Int]],[[f 0 :: Int,f x :: Int]]]
conjureHoles :: Conjurable f => f -> [Expr] Source #
Computes a list of holes encoded as Expr
s
from a Conjurable
functional value.
(cf. cjHoles
)
conjureTiersFor :: Conjurable f => f -> Expr -> [[Expr]] Source #
conjureAreEqual :: Conjurable f => f -> Int -> Expr -> Expr -> Bool Source #
Given a Conjurable
functional value,
computes a function that checks whether two Expr
s are equal
up to a given number of tests.
conjureMkEquation :: Conjurable f => f -> Expr -> Expr -> Expr Source #
Computes a function that makes an equation between two expressions.
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 | |
conjureIsDeconstruction :: Conjurable f => f -> Int -> Expr -> Bool Source #
Checks if an expression is a deconstruction.
There should be a single hole
in the expression.
It should decrease the size of all arguments that have a size greater than 0.
(cf. conjureIsDeconstructor
)
candidateDeconstructionsFrom :: Expr -> [Expr] Source #
Compute candidate deconstructions from an Expr
.
This is used in the implementation of candidateDefnsC
followed by conjureIsDeconstruction
.
> candidateDeconstructionsFrom (xx `mod'` yy) [ _ `mod` y , x `mod` _ ]
To be constrasted with candidateDeconstructionsFromHoled
.
candidateDeconstructionsFromHoled :: Expr -> [Expr] Source #
Compute candidate deconstructions from an Expr
.
This is used in the implementation of candidateExprs
followed by conjureIsDeconstruction
.
This is similar to canonicalVariations
but always leaves a hole
of the same return type as the given expression.
> candidateDeconstructionsFrom (i_ `mod'` i_) [ _ `mod` x , x `mod` _ ]
To be contrasted with candidateDeconstructionsFrom
conjureIsUnbreakable :: Conjurable f => f -> Expr -> Bool Source #
Checks if an Expr
is of an unbreakable type.
conjureReification :: Conjurable a => a -> [Reification1] Source #
Conjures a list of Reification1
for a Conjurable
type, its subtypes and Bool
.
This is used in the implementation of
conjureHoles
,
conjureMkEquation
,
conjureAreEqual
,
conjureTiersFor
,
conjureIsDeconstructor
,
conjureNamesFor
,
conjureIsUnbreakable
,
etc.
conjureReification1 :: Conjurable a => a -> Reification1 Source #
Conjures a Reification1
for a Conjurable
type.
This is used in the implementation of conjureReification
.
conjureDynamicEq :: Conjurable f => f -> Dynamic Source #
conjureIsNumeric :: Conjurable f => f -> Expr -> Bool Source #
ceval :: Conjurable f => Int -> f -> Defn -> f Source #
Evaluates a Defn
into a regular Haskell value
returning the given default value when there's a type mismatch.
The integer argument indicates the limit of recursive evaluations.
cevl :: Conjurable f => Int -> Defn -> f Source #
Evaluates a Defn
into a regular Haskell value
raising an error there's a type mismatch.
The integer argument indicates the limit of recursive evaluations.
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
conjureArgumentPats :: Conjurable f => [Expr] -> f -> [[[[Expr]]]] Source #
Returns a list of tiers of possible patterns for each argument.
The outer list has the same number of elements as the number of arguments of the given function.
This function is internal and only used in the implementation of conjurePats
.
It may be removed from the API without further notice.
It has been temporarily promoted to public to help refactor conjurePats
.
conjureMostGeneralCanonicalVariation :: Conjurable f => f -> Expr -> Expr Source #