-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | See readme.md -- -- See readme.md for description. @package numhask-free @version 0.0.1 -- |

What is a Free Algebra?

-- -- An algebra is a collection of operations which combine values to -- produce other values. Algebra is a posh way of saying "construction -- kit". The type of values an algebra combines and produces is called -- the carrier of the algebra. The collection of operations and -- specification of their arities is called the signature of the -- algebra. ~ pigworker reddit comment -- -- A free algebra then, can be a set of instructions for creating a free -- object from some initial structure or expression. FreeAlgebra -- can be thought of as busting up a computation into two parts: -- -- -- --

The free object

-- -- A free object over a set forgets everything about that set except -- some universal properties, specified by the word following free. For -- example, the free monoid over Integers forgets unique factorization, -- unique representation in every base, the GCD function, and everything -- else about the Integers except: they are a set of objects, there is an -- associative (binary) operation on Integers, and there is a "neutral" -- Integer; precisely the universal properties of monoids. ~ -- https://www.schoolofhaskell.com/user/bss/magma-tree -- -- ... informally, a free object over a set A can be thought of as -- being a "generic" algebraic structure over A: the only equations that -- hold between elements of the free object are those that follow from -- the defining axioms of the algebraic structure. ~ -- https://en.wikipedia.org/wiki/Free_object -- -- Explanations that lists are free monoids are abundant, as is research -- and development of free monadic combinators. Beyond this, concrete -- examples of free objects are rare out in the wild. -- --

Forgetting is central to a free algebra.

-- -- At the heart of constructing a free object is a forgetting that throws -- away the structural details of the very laws the free object defines. -- -- Adding a law to an algebra can be thought of as partitioning the -- carrier of the algebra into equivalence classes induced by that law, -- and regarding each class as one element. ~ The Boom -- Heirarchy -- -- In functorology, the free functor is left adjunct to a forgetful -- functor. To quote in full nLabs explanation: -- --
--   adjunction : free functor ⊣ forgetful functor
--   
-- -- elsewhere they then go on to say this about adjointness: -- -- Essentially everything that makes category theory nontrivial and -- interesting ... can be derived from the concept of adjoint -- functors. -- -- Stepping to the side of category theory, adjunctiveness is yet another -- metaphor for this deep dual nature of programming. That is, for every -- way of considering a problem, you can "flip the switch" and think -- about it in an opposite way or context. -- -- With respect to Free Algebra, the flipped switch is this: -- -- To arrive at the Free Object (where the only thing that is left -- are the laws under consideration), you need to forget the very laws -- encapsulated and remember everything else. -- -- this functor “forgets” the monoidal structure — once we are inside -- a plain set, we no longer distinguish the unit element or care about -- multiplication — it’s called a forgetful functor. ~ -- https://bartoszmilewski.com/2015/07/21/free-monoids/ -- --

A free ring is a recursive sequence of bags.

-- -- The main motivation of this library is a demonstration of coding paths -- to speed and safety. -- -- If haskell allowed subcategory functors, we could exactly say that the -- free ring is Free (Compose Bag Seq), a -- fairly compact specification. As it stands, the definition associates -- FreeRing with a forgetful functor representing a robust set of -- polymorphic fusion rules. There are a lot of things that are rings, -- and some of them need to go very fast and be very clean. -- -- And as is becoming well known, the easiest way to ensure that laws are -- never violated is by making their transgression non-representable, and -- free algebra is a useful technique for that. module NumHask.FreeAlgebra -- | A free algebra is a construction kit of operations and axioms that -- combine to produce values of a type. class FreeAlgebra initial free a | free -> initial -- | Convert from a structure (the initial type) to another structure, the -- free object, forgetting the algebraic laws encapsulated in the free -- object definition. forget :: FreeAlgebra initial free a => initial a -> free a -- | Create a free object from a carrier type singleton. lift :: FreeAlgebra initial free a => a -> free a -- | The algebra of the free object. -- --
--   lift . algebra == id
--   
algebra :: FreeAlgebra initial free a => free a -> a -- | Pretty print the free object. printf :: FreeAlgebra initial free a => free a -> Text -- | Starting from a particular initial structure, different sets of laws -- may lead to the same actual structure (or free object). Informal -- phantom type are included in most structures to help distinguish these -- cases and supply differeing instances. data NoLaws -- | A binary tree is a common initial structure when considering free -- algebras. -- -- The initial object for a Magma algebra is typically a tree-like -- structure representing a computation or expression; a series of binary -- operations, such as: -- --
--   (1 ⊕ 4) ⊕ ((7 ⊕ 12) ⊕ 0)
--   
-- --
--   >>> let m1 = Branch (Branch (Leaf (Example 1)) (Leaf (Example 4))) (Branch (Branch (Leaf (Example 7)) (Leaf (Example 12))) (Leaf (Example 0))) :: Tree MagmaOnly Example
--   
--   >>> putStrLn $ printf m1
--   ((1⊕4)⊕((7⊕12)⊕0))
--   
data Tree laws a Leaf :: a -> Tree laws a Branch :: Tree laws a -> Tree laws a -> Tree laws a -- | Convenience function to construct a Tree from a list with left bracket -- groupings. -- --
--   >>> toTreeL [1,4,7,12,0]
--   Branch (Branch (Branch (Branch (Leaf 1) (Leaf 4)) (Leaf 7)) (Leaf 12)) (Leaf 0)
--   
toTreeL :: NonEmpty a -> Tree NoLaws a -- | Construct a Tree from a list with a right bracket groupings. -- --
--   >>> toTreeR [1,4,7,12,0]
--   Branch (Leaf 1) (Branch (Leaf 4) (Branch (Leaf 7) (Branch (Leaf 12) (Leaf 0))))
--   
toTreeR :: NonEmpty a -> Tree NoLaws a -- | Where an algebra involves two (or more) operators, the initial -- structure (the expression) is arrived at by grafting new types of -- branches using sum types. data Exp a Value :: a -> Exp a Add :: Exp a -> Exp a -> Exp a Mult :: Exp a -> Exp a -> Exp a -- | Text parser for an expression. Parenthesis is imputed assuming -- multiplicative precedence and left-to-right default association. -- --
--   let t1 = "(4*(1+3)+(3+1)+6*(4+5*(11+6)*(3+2)))+(7+3+11*2)"
--   putStrLn . printf . parseExp $ t1
--   
-- -- ((((4*(1+3))+(3+1))+(6*(4+((5*(11+6))*(3+2)))))+((7+3)+(11*2))) parseExp :: Text -> Exp Int -- | Parse an Exp, forget to the FreeRing structure and print. -- --
--   >>> let t1 = "(4*(1+3)+(3+1)+6*(4+5*(11+6)*(3+2)))+(7+3+11*2)"
--   
--   >>> putStrLn $ freeExp t1
--   (1+3+3+7+(4*(1+3))+(6*(4+(5*(6+11)*(2+3))))+(11*2))
--   
freeExp :: Text -> Text -- | Free Algebra for a Magma -- --
--   a ⊕ b is closed
--   
-- -- Given an initial binary Tree structure: -- --
--   data Tree a = Leaf a | Branch (Tree a) (Tree a)
--   
-- -- , a closed binary operation (a magma) and no other laws, the free -- algebra is also a Tree. -- --
--   >>> let init = toTreeL $ Example <$> [1,4,7,12,0] :: Tree NoLaws Example
--   
--   >>> let free = forget init :: Tree MagmaOnly Example
--   
--   >>> putStrLn $ printf $ free
--   ((((1⊕4)⊕7)⊕12)⊕0)
--   
-- --
--   >>> algebra free
--   24
--   
data MagmaOnly -- |
--   unit ⊕ a = a
--   a ⊕ unit = a
--   
data UnitalOnly -- | The introduction of unital laws to the algebra changes what the free -- structure is, compared to the MagmaOnly case. From this -- library's point of view, that an algebra is an instruction kit for -- constructing an object, the unital laws are an instruction to -- substitute "a" for whenever "unit ⊕ a" occurs. Where an element is -- combined with the unit element, this operation should be erased and -- forgotten. -- -- For example, from the point of view of the free algebra, ((0 ⊕ 4) ⊕ 0) -- ⊕ 12 and 4 ⊕ 12 (say) are the same. The initial structure can be -- divided into equivalence classes where trees are isomorphic (the -- same). -- -- In contrast to the MagmaOnly case, the forgetting of unit operations -- means that an empty tree can result from an initially non-empty -- initial structure. The easiest way to represent this potential free -- object is simply to graft an EmptyTree tag to a Tree with a sum type. -- -- An EmptyTree represents a collapse of an initial structure down to -- nothing, as a result of applying the unital laws eg -- --
--   >>> let init = toTreeL $ Example <$> [0,0,0] :: Tree NoLaws Example
--   
--   >>> forget init :: TreeU UnitalOnly Example
--   EmptyTree
--   
-- -- By forgetting instances of the unital laws in the original -- expression, the unital laws cannot be violated in the free object -- because they no longer exist. -- --
--   >>> let init = toTreeL $ Example <$> [0,1,4,0,7,12,0] :: Tree NoLaws Example
--   
--   >>> putStrLn $ printf $ (forget init :: TreeU UnitalOnly Example)
--   (((1⊕4)⊕7)⊕12)
--   
data TreeU laws a EmptyTree :: TreeU laws a NonEmptyTree :: Tree MagmaOnly a -> TreeU laws a -- |
--   (a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)
--   
data AssociativeOnly -- | Introduction of an associative law induces an equivalence class where, -- for example, (1 ⊕ 2) ⊕ 3 and 1 ⊕ (2 ⊕ 3) should be represented in the -- same way. -- -- forget, the free object constructor, thus needs to forget about -- the tree shape (the brackets or parentheses of the original -- expression). -- -- As an algebra consumes an expression one element at a time, branches -- (or "links") still exist from one element to the next. The free object -- is still a tree structure, but it is the same tree shape. -- -- Forcing one side of the branch to be a value provides a tree structure -- that branches to the other side. The left branch as the value has been -- chosen in this representation but this is arbitrary. -- --
--   >>> let exl = toTreeL $ Example <$> [1,4,7,12,0]
--   
--   >>> putStrLn $ printf (forget exl :: Tree MagmaOnly Example)
--   ((((1⊕4)⊕7)⊕12)⊕0)
--   
-- --
--   >>> let exr = toTreeR $ Example <$> [1,4,7,12,0]
--   
--   >>> putStrLn $ printf (forget exr :: Tree MagmaOnly Example)
--   (1⊕(4⊕(7⊕(12⊕0))))
--   
-- --
--   >>> putStrLn $ printf (forget exl :: TreeA AssociativeOnly Example)
--   1⊕4⊕7⊕12⊕0
--   
-- --
--   >>> (\x -> (forget $ toTreeL x :: TreeA AssociativeOnly Example) == (forget $ toTreeR $ x :: TreeA AssociativeOnly Example)) (Example <$> [1,4,7,12,0])
--   True
--   
data TreeA laws a LeafA :: a -> TreeA laws a BranchA :: a -> TreeA laws a -> TreeA laws a -- |
--   a ⊕ b == b ⊕ a
--   
-- -- but non-associative, so -- --
--   (a ⊕ b) ⊕ c == (b ⊕ a) ⊕ c
--   
-- -- but -- --
--   (a ⊕ b) ⊕ c /= a ⊕ (b ⊕ c)
--   
-- -- Commutation requires a ⊕ b and b ⊕ a to be represented the same, and -- this induces a preordering: some form of (arbitrary) -- ordering is needed to consistently and naturally represent a ⊕ b and b -- ⊕ a as "ab". -- -- In structural terms, a commutative tree is a mobile; a tree that has -- lost it's left and rightedness. To implement this forgetting, the left -- element of BranchC is arbitrarily chosen as always being less than or -- equal to the right element. -- -- c1: 3 ⊕ (2 ⊕ 1) -- -- c2: 3 ⊕ (1 ⊕ 2) -- -- c3: (1 ⊕ 2) ⊕ 3 -- --
--   >>> let c1 = forget $ Branch (Leaf (Example 3)) (Branch (Leaf (Example 2)) (Leaf (Example 1))) :: Tree CommutativeOnly Example
--   
--   >>> let c2 = forget $ Branch (Leaf (Example 3)) (Branch (Leaf (Example 1)) (Leaf (Example 2))) :: Tree CommutativeOnly Example
--   
--   >>> let c3 = forget $ Branch (Branch (Leaf (Example 1)) (Leaf (Example 2))) (Leaf (Example 3)) :: Tree CommutativeOnly Example
--   
-- --
--   >>> c1 == c2
--   True
--   
-- --
--   >>> c1 == c3
--   True
--   
data CommutativeOnly -- |
--   inv a ⊕ (a ⊕ b) == b -- left cancellation
--   (a ⊕ b) ⊕ inv b == a -- right cancellation
--   
-- -- but -- --
--   inv a ⊕ a == unit
--   
-- -- is not a thing yet without a unit to equal to. -- -- The cancellation (or reversal or negation) of a value and the value -- are both lost in forming the equivalence relationship. Editing and -- diffing are two obvious examples. -- -- The data structure for the equivalence class is unchanged, so Tree can -- be reused. -- -- inv1: -1 ⊕ (1 ⊕ 5) == 5 -- -- inv2: (1 ⊕ 5) ⊕ -5 == 1 -- -- inv3: (1 ⊕ 5) ⊕ -1 == (1 ⊕ 5) ⊕ -1 -- --
--   >>> let inv1 = Branch (Leaf (Example (-1))) (Branch (Leaf (Example 1)) (Leaf (Example 5)))
--   
--   >>> let inv2 = Branch (Branch (Leaf (Example 1)) (Leaf (Example 5))) (Leaf (Example (-5)))
--   
--   >>> let inv3 = Branch (Branch (Leaf (Example 1)) (Leaf (Example 5))) (Leaf ((Example (-1))))
--   
--   >>> forget inv1 :: Tree InvertibleOnly Example
--   Leaf 5
--   
-- --
--   >>> putStrLn $ printf $ (forget inv3 :: Tree InvertibleOnly Example)
--   ((1⊕5)⊕-1)
--   
data InvertibleOnly -- |
--   a ⊕ a = a
--   
-- -- Immediately repeated elements are forgotten in the equivalence class -- object. -- -- idem1: (5 ⊕ 5) ⊕ 1 == 5 ⊕ 1 -- -- idem2: (1 ⊕ 5) ⊕ (1 ⊕ 5) == (1 ⊕ 5) -- -- but -- -- idem3: (1 ⊕ 5) ⊕ 5 == (1 ⊕ 5) ⊕ 5 -- -- because we don't yet have associativity. -- --
--   >>> let idem1 = Branch (Branch (Leaf (Example 5)) (Leaf (Example 5))) (Leaf (Example 1))
--   
--   >>> let idem2 = Branch (Branch (Leaf (Example 1)) (Leaf (Example 5))) (Branch (Leaf (Example 1)) (Leaf  (Example 5)))
--   
--   >>> let idem3 = Branch (Branch (Leaf (Example 1)) (Leaf (Example 5))) (Leaf (Example 5))
--   
--   >>> putStrLn $ printf (forget idem1 :: Tree IdempotentOnly Example)
--   (5 o 1)
--   
-- --
--   >>> putStrLn $ printf (forget idem2 :: Tree IdempotentOnly Example)
--   (1 o 5)
--   
-- --
--   >>> putStrLn $ printf (forget idem3 :: Tree IdempotentOnly Example)
--   ((1 o 5) o 5)
--   
-- --
--   >>> algebra (forget idem3 :: Tree IdempotentOnly Example)
--   5
--   
data IdempotentOnly -- |
--   e ⊕ a == e  left absorbing
--   a ⊕ e == e  right absorbing
--   
-- -- The absorbed element is forgotten. -- -- ab1: 0 * (2 * 5) == 0 -- -- ab2: (2 * 5) * 0 == 0 -- --
--   >>> let ab1 = Branch (Leaf (Example 0)) (Branch (Leaf (Example 2)) (Leaf (Example 5)))
--   
--   >>> let ab2 = Branch (Branch (Leaf (Example 2)) (Leaf (Example 5))) (Leaf (Example 0))
--   
--   >>> forget ab1 :: Tree AbsorbingOnly Example
--   Leaf 0
--   
-- --
--   >>> forget ab2 :: Tree AbsorbingOnly Example
--   Leaf 0
--   
data AbsorbingOnly -- | The free monoid is a list. -- -- Applying unital and associativity laws in the context of converting an -- expression tree into a free monoid, the simplest structure possible, -- involves: -- -- -- -- So, starting with the initial tree: -- --
--   data Tree a = Leaf a | Branch (Tree a) (Tree a)
--   
-- -- We graft on a sum tag to represent an empty structure: -- --
--   data Tree a = EmptyTree | Leaf a | Branch (Tree a) (Tree a)
--   
-- -- To forget the left/right structure of the tree we force the -- left side of the branch to be a value rather than another tree branch, -- so that the whole tree always branches to the right: -- --
--   data Tree a = EmptyTree | Leaf a | Branch a (Tree a)
--   
-- -- Leaf a can be represented as Branch a EmptyTree, so we can simplify -- this to: -- --
--   data Tree a = EmptyTree | Branch a (Tree a)
--   
-- -- And this is the classical Haskell cons list with different names: -- --
--   data [] a = [] | a : [a]
--   
newtype FreeMonoid laws a FreeMonoid :: [a] -> FreeMonoid laws a [leaves] :: FreeMonoid laws a -> [a] -- | Multiplicative monoid laws -- --
--   a * b is closed
--   one * a = a
--   a * one = a
--   (a * b) * c = a * (b * c)
--   
-- --
--   >>> one :: FreeMonoid MultMonoid Int
--   FreeMonoid {leaves = []}
--   
-- -- ex1: (1 * 2) * (4 * 5) * 1 -- --
--   >>> let ex1 = Branch (Branch (Branch (Leaf 1) (Leaf 2)) (Branch (Leaf 4) (Leaf 5))) (Leaf 1)
--   
-- --
--   >>> putStrLn $ printf (forget ex1 :: FreeMonoid MultMonoid Int)
--   (2*4*5)
--   
-- --
--   >>> algebra (forget ex1 :: FreeMonoid MultMonoid Int)
--   40
--   
data MultMonoid -- | The Free commutative monoid is a Bag. -- -- In addition to the forgetting needed for the free monoid, forgetting -- additions of zero and forgetting brackets, a commutative law means -- forgetting the order of the original expression structure. -- -- A list that has lost it's order is sometimes referred to as a bag. An -- efficient representation of a bag is a (key,value) pair where the keys -- are elements in the initial expression and values are the number of -- times the element has occurred. -- -- In the usual surface-paradox typical of adjointness, the forgetting of -- the ordering of the initial structure induces a requirement that the -- carrier type be ordered. newtype Bag laws a Bag :: Map a Int -> Bag laws a [unbag] :: Bag laws a -> Map a Int -- | This is a functor from Ord -> Ord but, sadly, not a functor from -- Hask -> Hask mapBag :: Ord b => (a -> b) -> Bag laws a -> Bag laws b -- | Additive Commutative Group Laws -- --
--   a + b is closed
--   zero + a = a
--   a + zero = a
--   (a + b) + c = a + (b + c)
--   a + b == b + a
--   a + negate a = zero
--   
-- -- Adding invertibility to the list of laws for a commutative monoid gets -- us to the definition of a Commutative (or Abelian) Group. -- -- Invertible (in combination with commutation) means forgetting a value -- when the inversion of the value is contained somewhere within the -- expression. For example, armed with a definition of what a negative -- number is, integer addition such as: -- --
--   1+2+3+-1+-4+2
--   
-- -- Can be represented as a bag of 2 2's, one 3 and minus one 4's. -- --
--   >>> let exbag = fromList [1,2,3,-1,-4,-2] :: Bag AddCommGroup Int
--   
--   >>> exbag
--   Bag {unbag = fromList [(3,1),(4,-1)]}
--   
-- --
--   >>> toList exbag
--   [3,-4]
--   
-- --
--   >>> exAdd = toTreeL [0,1,2,3,0,-1,-4,-2,0]
--   
--   >>> putStrLn $ printf (forget exAdd :: Bag AddCommGroup Int)
--   (3+-4)
--   
data AddCommGroup -- | Ring Laws -- --
--   a + b is closed
--   zero + a = a
--   a + zero = a
--   (a + b) + c = a + (b + c)
--   a + b == b + a
--   a + negate a = zero
--   a * b is closed
--   one * a = a
--   a * one = a
--   (a * b) * c = a * (b * c)
--   a * zero = zero
--   zero * a = zero
--   a * (b + c) = (a * b) + (a * c)
--   (b + c) * a = (b * a) + (c * a)
--   
data RingLaws -- | The free ring is a recursive sequence of bags. -- -- Given multiplication is monoidal (with the free object a list) and -- addition is a commutative group (with the free object a bag), it seems -- intuitively the case that the free object for a ring is a recursive -- list of bags. It is recursive because the ordering of +'s and *'s does -- not reduce, so that the tree-like nature of the expression is not -- forgotten. -- -- Abstractly, the choice of what goes in what should be an arbitrary -- one; the free object could also be a (recursive) bag of lists. The -- addition collection structure feels like it should be within the -- multiplication structure, however, because of the distribution law -- equivalence that need to be honoured in the representation: -- --
--   a ⋅ (b + c) = (a · b) + (a · c)
--   (b + c) · a = (b · a) + (c · a)
--   
-- -- It is likely, in most endeavours, that multiplication is more -- expensive than addition, and the left hand side of these equations -- have less multiplications. -- -- Because the distribution laws are substitutions to both the left and -- the right, use of Seq is indicated instead of a list (which is -- isomorphic to a list and thus allowed as an alternative). -- -- The free ring is the same general shape as the free monad in the -- free library -- --
--   data Free f a = Pure a | Free (f (Free f a))
--   
-- -- which in turn is almost the same shape as Fix eg -- --
--   newtype Fix f = Fix (f (Fix f))
--   
-- -- If Bag could form a Functor instance, then the Free Ring could be -- expressed as: -- --
--   data FreeRing a = 'Free' ('Compose' 'Bag' 'Seq') a
--   
-- -- which is a very clean result. data FreeRing laws a FreeV :: a -> FreeRing laws a FreeR :: Seq (Bag AddCommGroup (FreeRing laws a)) -> FreeRing laws a -- | example magma (⊕) :: Magma a => a -> a -> a -- | example type newtype Example Example :: Int -> Example -- | informal test suite -- -- empty expression -- --
--   >>> freeExp "0"
--   "0"
--   
-- -- plain (with multiplicative precedence) -- --
--   >>> forget $ parseExp "1+2*3" :: FreeRing RingLaws Int
--   FreeR (fromList [Bag {unbag = fromList [(FreeV 1,1),(FreeR (fromList [Bag {unbag = fromList [(FreeV 2,1)]},Bag {unbag = fromList [(FreeV 3,1)]}]),1)]}])
--   
-- --
--   >>> freeExp "1+2*3"
--   "(1+(2*3))"
--   
-- -- Additive unital -- --
--   >>> freeExp "0+(2+0)*3+0"
--   "(2*3)"
--   
-- -- General additive associative and commutation -- --
--   >>> freeExp "(1+2)*3+(4+5)+6*7"
--   "(4+5+((1+2)*3)+(6*7))"
--   
-- -- Multiplicative unital -- --
--   >>> freeExp "1*3+4*1+1*(5*6)"
--   "(3+4+(5*6))"
--   
-- -- Multiplicative association (not commutative) -- --
--   >>> freeExp "(2*6)*((4*5)*2)"
--   "(2*6*4*5*2)"
--   
-- -- absorbative -- --
--   >>> freeExp "0*1+3*(3+4)*0"
--   "0"
--   
-- -- additive invertible -- --
--   >>> freeExp "(1+2)+(-1+-2)"
--   "0"
--   
-- -- distribution -- --
--   a ⋅ (b + c) = (a · b) + (a · c)
--   (b + c) · a = (b · a) + (c · a)
--   
-- -- left -- --
--   >>> freeExp "2*(3+4)+2*5+2*6"
--   "(2*(3+4+5+6))"
--   
-- -- right -- --
--   >>> freeExp "(3+4)*2+5*2+6*2"
--   "((3+4+5+6)*2)"
--   
-- -- mixed (left then right checks) -- --
--   >>> freeExp "2*(3+4)*2+5*2+2*6*2"
--   "((5+(2*(3+4))+(2*6))*2)"
--   
-- -- Note that "(2*(3+4+6)*2+5*2)" is a valid alternative to what the -- current FreeRing forget function comes up with. -- --

TODO: optional extras:

-- -- -- --
--   (a . b) + a ==> a . (b + one)
--   
-- -- -- -- lifting an (additive bag) to a multiplication sequence -- --
--   3+3+3+3 ==> 3*4
--   
-- -- -- --
--   3*3*3*3 ==> 3^4
--   
data InformalTests -- | intercalate elements of an expression with an operator, and put -- brackets around this. calate :: Text -> [Text] -> Text instance GHC.Show.Show NumHask.FreeAlgebra.BadExpParse instance GHC.Show.Show a => GHC.Show.Show (NumHask.FreeAlgebra.FreeRing laws a) instance GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.FreeAlgebra.FreeRing laws a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.FreeAlgebra.FreeRing laws a) instance GHC.Base.Functor NumHask.FreeAlgebra.Exp instance GHC.Show.Show a => GHC.Show.Show (NumHask.FreeAlgebra.Exp a) instance GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.FreeAlgebra.Exp a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.FreeAlgebra.Exp a) instance GHC.Show.Show a => GHC.Show.Show (NumHask.FreeAlgebra.Bag laws a) instance GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.FreeAlgebra.Bag laws a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.FreeAlgebra.Bag laws a) instance GHC.Show.Show a => GHC.Show.Show (NumHask.FreeAlgebra.FreeMonoid laws a) instance Data.Foldable.Foldable (NumHask.FreeAlgebra.FreeMonoid laws) instance GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.FreeAlgebra.FreeMonoid laws a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.FreeAlgebra.FreeMonoid laws a) instance GHC.Base.Functor (NumHask.FreeAlgebra.TreeA laws) instance GHC.Show.Show a => GHC.Show.Show (NumHask.FreeAlgebra.TreeA laws a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.FreeAlgebra.TreeA laws a) instance GHC.Base.Functor (NumHask.FreeAlgebra.TreeU laws) instance GHC.Show.Show a => GHC.Show.Show (NumHask.FreeAlgebra.TreeU laws a) instance GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.FreeAlgebra.TreeU laws a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.FreeAlgebra.TreeU laws a) instance NumHask.Algebra.Abstract.Group.Idempotent NumHask.FreeAlgebra.Example instance NumHask.Algebra.Abstract.Group.Commutative NumHask.FreeAlgebra.Example instance NumHask.Algebra.Abstract.Group.Associative NumHask.FreeAlgebra.Example instance GHC.Classes.Ord NumHask.FreeAlgebra.Example instance GHC.Classes.Eq NumHask.FreeAlgebra.Example instance GHC.Base.Functor (NumHask.FreeAlgebra.Tree laws) instance GHC.Show.Show a => GHC.Show.Show (NumHask.FreeAlgebra.Tree laws a) instance GHC.Classes.Ord a => GHC.Classes.Ord (NumHask.FreeAlgebra.Tree laws a) instance GHC.Classes.Eq a => GHC.Classes.Eq (NumHask.FreeAlgebra.Tree laws a) instance GHC.Exception.Type.Exception NumHask.FreeAlgebra.BadExpParse instance (GHC.Classes.Eq a, GHC.Classes.Ord a, NumHask.Algebra.Abstract.Additive.Subtractive a, NumHask.Algebra.Abstract.Multiplicative.Multiplicative a) => NumHask.Algebra.Abstract.Multiplicative.Multiplicative (NumHask.FreeAlgebra.FreeRing NumHask.FreeAlgebra.RingLaws a) instance (GHC.Classes.Ord a, NumHask.Algebra.Abstract.Ring.Ring a) => NumHask.Algebra.Abstract.Additive.Additive (NumHask.FreeAlgebra.FreeRing NumHask.FreeAlgebra.RingLaws a) instance (GHC.Show.Show a, GHC.Classes.Ord a, NumHask.Algebra.Abstract.Ring.Ring a) => NumHask.Algebra.Abstract.Additive.Subtractive (NumHask.FreeAlgebra.FreeRing NumHask.FreeAlgebra.RingLaws a) instance (GHC.Show.Show a, GHC.Classes.Eq a, GHC.Classes.Ord a, NumHask.Algebra.Abstract.Ring.Ring a) => NumHask.FreeAlgebra.FreeAlgebra NumHask.FreeAlgebra.Exp (NumHask.FreeAlgebra.FreeRing NumHask.FreeAlgebra.RingLaws) a instance (GHC.Show.Show a, GHC.Classes.Eq a, NumHask.Algebra.Abstract.Ring.Ring a, NumHask.Algebra.Abstract.Group.Magma a) => NumHask.FreeAlgebra.FreeAlgebra NumHask.FreeAlgebra.Exp NumHask.FreeAlgebra.Exp a instance (GHC.Classes.Ord a, NumHask.Algebra.Abstract.Additive.Subtractive a) => GHC.Exts.IsList (NumHask.FreeAlgebra.Bag NumHask.FreeAlgebra.AddCommGroup a) instance GHC.Classes.Ord a => NumHask.Algebra.Abstract.Additive.Additive (NumHask.FreeAlgebra.Bag NumHask.FreeAlgebra.AddCommGroup a) instance GHC.Classes.Ord a => NumHask.Algebra.Abstract.Additive.Subtractive (NumHask.FreeAlgebra.Bag NumHask.FreeAlgebra.AddCommGroup a) instance (GHC.Show.Show a, GHC.Classes.Eq a, GHC.Classes.Ord a, NumHask.Algebra.Abstract.Additive.Subtractive a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.Bag NumHask.FreeAlgebra.AddCommGroup) a instance NumHask.Algebra.Abstract.Multiplicative.Multiplicative (NumHask.FreeAlgebra.FreeMonoid NumHask.FreeAlgebra.MultMonoid a) instance (GHC.Show.Show a, GHC.Classes.Eq a, NumHask.Algebra.Abstract.Multiplicative.Multiplicative a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.FreeMonoid NumHask.FreeAlgebra.MultMonoid) a instance (GHC.Show.Show a, GHC.Classes.Eq a, NumHask.Algebra.Abstract.Group.Absorbing a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.AbsorbingOnly) a instance (GHC.Show.Show a, GHC.Classes.Ord a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.IdempotentOnly) a instance (GHC.Show.Show a, GHC.Classes.Eq a, NumHask.Algebra.Abstract.Group.Invertible a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.InvertibleOnly) a instance (GHC.Show.Show a, GHC.Classes.Ord a, NumHask.Algebra.Abstract.Group.Commutative a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.CommutativeOnly) a instance (GHC.Show.Show a, NumHask.Algebra.Abstract.Group.Associative a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.TreeA NumHask.FreeAlgebra.AssociativeOnly) a instance (GHC.Classes.Eq a, GHC.Show.Show a, NumHask.Algebra.Abstract.Group.Unital a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.TreeU NumHask.FreeAlgebra.UnitalOnly) a instance (GHC.Show.Show a, NumHask.Algebra.Abstract.Group.Magma a) => NumHask.FreeAlgebra.FreeAlgebra (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.NoLaws) (NumHask.FreeAlgebra.Tree NumHask.FreeAlgebra.MagmaOnly) a instance NumHask.Algebra.Abstract.Group.Magma NumHask.FreeAlgebra.Example instance NumHask.Algebra.Abstract.Group.Unital NumHask.FreeAlgebra.Example instance NumHask.Algebra.Abstract.Group.Absorbing NumHask.FreeAlgebra.Example instance NumHask.Algebra.Abstract.Group.Invertible NumHask.FreeAlgebra.Example instance GHC.Show.Show NumHask.FreeAlgebra.Example