úΑøˆĖK      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJportable experimentalEdward Kmett <ekmett@gmail.com> Safe-Inferred a p w replaces the free variable a with p in w. 9substitute "hello" ["goodnight","Gracie"] ["hello","!!!"]["goodnight","Gracie","!!!"] a b w replaces a free variable a with another free variable b in w. 5substituteVar "Alice" "Bob" ["Alice","Bob","Charlie"]["Bob","Bob","Charlie"]CIf a term has no free variables, you can freely change the type of ( free variables it is parameterized on.  closed [12]Nothing closed ""Just [] :t closed ""closed "" :: Maybe [b]%A closed term has no free variables.  isClosed []TrueisClosed [1,2,3]Falseportable experimentalEdward Kmett <ekmett@gmail.com> Safe-Inferred Instances of $ generate left modules over monads. 3This means they should satisfy the following laws:   m >>>= return "a m , m >>>= (ŧ x !’ k x >>= h) "a (m >>>= k) >>>= EThis guarantees that a typical Monad instance for an expression type B where Bound instances appear will satisfy the Monad laws (see doc/BoundLaws.hs). 3If instances of Bound are monad transformers, then m  f "a m K L M f @ implies the above laws, and is in fact the default definition. CThis is useful for types like expression lists, case alternatives, I schemas, etc. that may not be expressions in their own right, but often  contain expressions. Perform substitution If t is an instance of  MonadTrans0 and you are compiling on GHC >= 7.4, then this  gets the default definition: m  f = m K L M fA flipped version of (). () = N ()portable experimentalEdward Kmett <ekmett@gmail.com> Trustworthy"I am not a number, I am a  free monad!" A  b a" is a variable that may either be "bound" ( ) or "free" (). G(It is also technically a free monad in the same near-trivial sense as  O.) this is a free variable this is a bound variable  P QRSTUVWXYZ[\]^_`abcdefgh    P QRSTUVWXYZ[\]^_`abcdefghportable experimentalEdward Kmett <ekmett@gmail.com> Trustworthy   b f a is an f$ expression with bound variables in b,  and free variables in a 8We store bound variables as their generalized de Bruijn  representation in that we're allowed to L (using  ) an entire 8 tree rather than only succ individual variables, but we' re still  only allowed to do so once per  . Weakening trees permits  O(1)< weakening and permits more sharing opportunities. Here the " deBruijn 0 is represented by the   constructor of  , while the  de Bruijn i6 (which may be applied to an entire tree!) is handled  by . 6NB: equality and comparison quotient out the distinct  placements D allowed by the generalized de Bruijn representation and return the > same result as a traditional de Bruijn representation would. ELogically you can think of this as if the shape were the traditional   f (Var b a), but the extra f a inside permits us a cheaper L. 6Capture some free variables in an expression to yield  a   with bound variables in b :m + Data.List$abstract (`elemIndex` "bar") "barry"Scope [B 0,B 1,B 2,B 2,F "y"] Abstract over a single variable abstract1 'x' "xyz"Scope [B (),F "y",F "z"]1Enter a scope, instantiating all bound variables :m + Data.ListLinstantiate (\x -> [toEnum (97 + x)]) $ abstract (`elemIndex` "bar") "barry""abccy"Enter a  + that binds one variable, instantiating it +instantiate1 "x" $ Scope [B (),F "y",F "z"]"xyz"* quotients out the possible placements of  in   H by distributing them all to the leaves. This yields a more traditional 0 de Bruijn indexing scheme for bound variables. Since,   M  "a j we know that   M  M  "a and therefore ( . ) is idempotent. EConvert from traditional de Bruijn to generalized de Bruijn indices. $This requires a full tree traversal ;Perform substitution on both bound and free variables in a  . ;Return a list of occurences of the variables bound by this  . 2Perform a change of variables on bound variables. JPerform a change of variables, reassigning both bound and free variables. >Perform a change of variables on bound variables given only a k  instance  A version of ) that can be used when you only have the k  instance CObtain a result by collecting information from both bound and free  variables CObtain a result by collecting information from both bound and free  variables l the bound variables in a  . m@ both the variables bound by this scope and any free variables. -mapM_ over the variables bound by this scope !A ' that can be used when you only have a k  instance "'Traverse both bound and free variables #'Traverse both bound and free variables $(mapM over both bound and free variables %A #' that can be used when you only have a k  instance nCThe monad permits substitution on free variables, while preserving  bound variables op< is provides a list (with duplicates) of the free variables 0  !"#$%&'qrstuvwxyz{|}~€n‚oƒ  !"#$%&'  !"#$%&'.  !"#$%&'qrstuvwxyz{|}~€n‚oƒportable experimentalEdward Kmett <ekmett@gmail.com> Trustworthy(We track the choice of ( n% as a forgettable property that does not affect  the result of („) or …. )To compare names rather than values, use ( … *) instead. * Extract the *. +This provides an Iso+ that can be used to access the parts of a (.   + :: Iso (( n a) (( m b) (n, a) (m, b) ,.Abstraction, capturing named bound variables. - Abstract over a single variable .MEnter a scope, instantiating all bound variables, but discarding (comonadic)  meta data, like its name /Enter a  4 that binds one (named) variable, instantiating it. / = !()*+,-./†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œž()*+,-./()+*,-./ ()*+,-./†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžportable experimentalEdward Kmett <ekmett@gmail.com> Trustworthy00 b f a is an f$ expression with bound variables in b,  and free variables in a 5This implements traditional de Bruijn indices, while    + implements generalized de Bruijn indices. CThese traditional indices can be used to test the performance gain  of generalized indices. While this type 0 is identical to    2 this module focuses on a drop-in replacement for   . @Another use case is for syntaxes not stable under substitution,  therefore with only a Ÿ instance and no k instance. 36Capture some free variables in an expression to yield  a 0 with bound variables in b :m + Data.List$abstract (`elemIndex` "bar") "barry"Scope [B 0,B 1,B 2,B 2,F 'y']4 Abstract over a single variable abstract1 'x' "xyz"Scope [B (),F 'y',F 'z']51Enter a scope, instantiating all bound variables :m + Data.ListLinstantiate (\x -> [toEnum (97 + x)]) $ abstract (`elemIndex` "bar") "barry""abccy"6Enter a 0+ that binds one variable, instantiating it +instantiate1 "x" $ Scope [B (),F 'y',F 'z']"xyz"77 is just another name for 2 and is exported  to mimick  .  In particular no k constraint is required. 88 is just another name for 0 and is exported  to mimick .  In particular no k constraint is required. 9;Perform substitution on both bound and free variables in a 0. :;Return a list of occurences of the variables bound by this 0. ;2Perform a change of variables on bound variables. <JPerform a change of variables, reassigning both bound and free variables. =>Perform a change of variables on bound variables given only a k  instance > A version of <) that can be used when you only have the k  instance ?CObtain a result by collecting information from both bound and free  variables @CObtain a result by collecting information from both bound and free  variables Al the bound variables in a 0. Bm@ both the variables bound by this scope and any free variables. C-mapM_ over the variables bound by this scope DA B' that can be used when you only have a k  instance E'Traverse both bound and free variables F'Traverse both bound and free variables G(mapM over both bound and free variables HA F' that can be used when you only have a k  instance  CThe monad permits substitution on free variables, while preserving  bound variables Ąp< is provides a list (with duplicates) of the free variables /0123456789:;<=>?@ABCDEFGHIJĒĢĪĨͧĻĐŠŦŽ­ŪŊ°ą ēĄģ0123456789:;<=>?@ABCDEFGHIJ0123456789:;<=>?@ABCDEFGHIJ-0123456789:;<=>?@ABCDEFGHIJĒĢĪĨͧĻĐŠŦŽ­ŪŊ°ą ēĄģ portable experimentalEdward Kmett <ekmett@gmail.com> Safe-Inferred   ī     !"#$%&'()*+,-./0122345678    !"#$%&'()*+,-./019:;<=>9:?9:@9ABCDEFGHIJKLMNOPQRSTUVWXYZ[9\]9:^9:_9`a9bcde9`fghijklmnopqrstuvwxyz{|z{}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–9:—deghijklmnopqrstuvxy˜ bound-0.9 Bound.Term Bound.Class Bound.Var Bound.Scope Bound.NameBound.Scope.Simple Data.FunctiononBoundScopeControl.Monad.TransEitherT fromScopetoScope substitute substituteVarclosedisClosed>>>==<<<VarFBunvar_B_Funscopeabstract abstract1 instantiate instantiate1splatbindingsmapBoundmapScope liftMBound liftMScope foldMapBound foldMapScopetraverseBound_traverseScope_ mapMBound_ mapMScope_ traverseBound traverseScope mapMBound mapMScopeserializeScopedeserializeScopeNamename_Name abstractName abstract1NameinstantiateNameinstantiate1NamebaseGHC.Base>>=transformers-0.3.0.0Control.Monad.Trans.Classlift.flip Data.EitherEither distinguisher $fRead1Var $fShow1Var $fOrd1Var$fEq1Var $fRead2Var $fShow2Var $fOrd2Var$fEq2Var$fBitraversableVar$fBifoldableVar$fBifunctorVar $fMonadVar$fApplicativeVar$fTraversableVar $fFoldableVar $fFunctorVar$fSerializeVar $fBinaryVar $fSerialVar $fSerial1Var $fSerial2Var $fHashableVar$fHashable1Var$fHashable2VarGHC.EnumsuccidMonad Data.Foldable traverse_Data.Traversabletraverse $fMonadScope$fFoldableScopetoList$fSerializeScope $fBinaryScope $fSerialScope$fSerial1Scope$fHashableScope$fHashable1Scope $fBoundScope $fRead1Scope $fReadScope $fShow1Scope $fShowScope $fOrd1Scope $fOrdScope $fEq1Scope $fEqScope$fMonadTransScope$fApplicativeScope$fTraversableScope$fFunctorScopeghc-prim GHC.Classes==compare$fSerializeName $fBinaryName $fSerialName $fSerial1Name $fSerial2Name $fRead2Name $fShow2Name $fOrd2Name $fEq2Name $fRead1Name $fShow1Name $fOrd1Name $fEq1Name $fComonadName$fBitraversableName$fBifoldableName$fBifunctorName$fTraversableName$fFoldableName $fFunctorName $fOrdName$fHashableName$fHashable1Name$fHashable2Name$fEqNameFunctor