hobbits-1.3.1: A library for canonically representing terms with binding
Copyright(c) 2011 Edwin Westbrook Nicolas Frisby and Paul Brauner
LicenseBSD3
Maintaineremw4@rice.edu
Stabilityexperimental
PortabilityGHC
Safe HaskellNone
LanguageHaskell2010

Data.Binding.Hobbits.Mb

Description

This module defines multi-bindings as the type Mb, as well as a number of operations on multi-bindings. See the paper E. Westbrook, N. Frisby, P. Brauner, "Hobbits for Haskell: A Library for Higher-Order Encodings in Functional Programming Languages" for more information.

Synopsis

Abstract types

data Name (a :: k) Source #

A Name a is a bound name that is associated with type a.

Instances

Instances details
TestEquality (Name :: k -> Type) Source # 
Instance details

Defined in Data.Binding.Hobbits.Internal.Name

Methods

testEquality :: forall (a :: k0) (b :: k0). Name a -> Name b -> Maybe (a :~: b) #

NuMatchingAny1 (Name :: k -> Type) Source # 
Instance details

Defined in Data.Binding.Hobbits.NuMatching

Methods

nuMatchingAny1Proof :: forall (a :: k0). MbTypeRepr (Name a) Source #

Eq (Name a) Source # 
Instance details

Defined in Data.Binding.Hobbits.Internal.Name

Methods

(==) :: Name a -> Name a -> Bool #

(/=) :: Name a -> Name a -> Bool #

Ord (Name a) Source # 
Instance details

Defined in Data.Binding.Hobbits.Internal.Name

Methods

compare :: Name a -> Name a -> Ordering #

(<) :: Name a -> Name a -> Bool #

(<=) :: Name a -> Name a -> Bool #

(>) :: Name a -> Name a -> Bool #

(>=) :: Name a -> Name a -> Bool #

max :: Name a -> Name a -> Name a #

min :: Name a -> Name a -> Name a #

Show (Name a) Source # 
Instance details

Defined in Data.Binding.Hobbits.Internal.Name

Methods

showsPrec :: Int -> Name a -> ShowS #

show :: Name a -> String #

showList :: [Name a] -> ShowS #

NuMatching (Name a) Source # 
Instance details

Defined in Data.Binding.Hobbits.NuMatching

Show (RAssign (Name :: k -> Type) c) Source # 
Instance details

Defined in Data.Binding.Hobbits.Internal.Name

type Binding (a :: k) = Mb (RNil :> a) Source #

A Binding is simply a multi-binding that binds one name

data Mb (ctx :: RList k) b Source #

An Mb ctx b is a multi-binding that binds one name for each type in ctx, where ctx has the form RNil :> t1 :> ... :> tn. Internally, multi-bindings are represented either as "fresh functions", which are functions that quantify over all fresh names that have not been used before and map them to the body of the binding, or as "fresh pairs", which are pairs of a list of names that are guaranteed to be fresh along with a body. Note that fresh pairs must come with an MbTypeRepr for the body type, to ensure that the names given in the pair can be relaced by fresher names.

Instances

Instances details
Functor (Mb ctx) Source # 
Instance details

Defined in Data.Binding.Hobbits.Mb

Methods

fmap :: (a -> b) -> Mb ctx a -> Mb ctx b #

(<$) :: a -> Mb ctx b -> Mb ctx a #

TypeCtx ctx => Applicative (Mb ctx) Source # 
Instance details

Defined in Data.Binding.Hobbits.Mb

Methods

pure :: a -> Mb ctx a #

(<*>) :: Mb ctx (a -> b) -> Mb ctx a -> Mb ctx b #

liftA2 :: (a -> b -> c) -> Mb ctx a -> Mb ctx b -> Mb ctx c #

(*>) :: Mb ctx a -> Mb ctx b -> Mb ctx b #

(<*) :: Mb ctx a -> Mb ctx b -> Mb ctx a #

Eq a => Eq (Mb ctx a) Source # 
Instance details

Defined in Data.Binding.Hobbits.Liftable

Methods

(==) :: Mb ctx a -> Mb ctx a -> Bool #

(/=) :: Mb ctx a -> Mb ctx a -> Bool #

Show a => Show (Mb c a) Source # 
Instance details

Defined in Data.Binding.Hobbits.Mb

Methods

showsPrec :: Int -> Mb c a -> ShowS #

show :: Mb c a -> String #

showList :: [Mb c a] -> ShowS #

NuMatching a => NuMatching (Mb ctx a) Source # 
Instance details

Defined in Data.Binding.Hobbits.NuMatching

Multi-binding constructors

nu :: forall k1 (a :: k1) (b :: *). (Name a -> b) -> Binding a b Source #

nu f creates a binding which binds a fresh name n and whose body is the result of f n.

nuMulti :: RAssign f ctx -> (RAssign Name ctx -> b) -> Mb ctx b Source #

The expression nuMulti p f creates a multi-binding of zero or more names, one for each element of the vector p. The bound names are passed the names to f, which returns the body of the multi-binding. The argument p, of type RAssign f ctx, acts as a "phantom" argument, used to reify the list of types ctx at the term level; thus it is unimportant what the type function f is.

nus :: forall k (f :: k -> Type) (ctx :: RList k) b. RAssign f ctx -> (RAssign (Name :: k -> Type) ctx -> b) -> Mb ctx b Source #

nus = nuMulti

emptyMb :: a -> Mb RNil a Source #

Creates an empty binding that binds 0 names.

extMb :: Mb ctx a -> Mb (ctx :> tp) a Source #

Extend the context of a name-binding by adding a single type

extMbMulti :: RAssign f ctx2 -> Mb ctx1 a -> Mb (ctx1 :++: ctx2) a Source #

Extend the context of a name-binding with multiple types

Queries on names

cmpName :: Name a -> Name b -> Maybe (a :~: b) Source #

cmpName n m compares names n and m of types Name a and Name b, respectively. When they are equal, Some e is returned for e a proof of type a :~: b that their types are equal. Otherwise, None is returned.

For example:

nu $ \n -> nu $ \m -> cmpName n n   ==   nu $ \n -> nu $ \m -> Some Refl
nu $ \n -> nu $ \m -> cmpName n m   ==   nu $ \n -> nu $ \m -> None

hcmpName :: forall k1 k2 (a :: k1) (b :: k2). Name a -> Name b -> Maybe (a :~~: b) Source #

Heterogeneous comparison of names, that could be at different kinds

mbNameBoundP :: forall k1 k2 (a :: k1) (ctx :: RList k2). Mb ctx (Name a) -> Either (Member ctx a) (Name a) Source #

Checks if a name is bound in a multi-binding, returning Left mem when the name is bound, where mem is a proof that the type of the name is in the type list for the multi-binding, and returning Right n when the name is not bound, where n is the name.

For example:

nu $ \n -> mbNameBoundP (nu $ \m -> m)  ==  nu $ \n -> Left Member_Base
nu $ \n -> mbNameBoundP (nu $ \m -> n)  ==  nu $ \n -> Right n

mbCmpName :: forall k1 k2 (a :: k1) (b :: k1) (c :: RList k2). Mb c (Name a) -> Mb c (Name b) -> Maybe (a :~: b) Source #

Compares two names inside bindings, taking alpha-equivalence into account; i.e., if both are the ith name, or both are the same name not bound in their respective multi-bindings, then they compare as equal. The return values are the same as for cmpName, so that Some Refl is returned when the names are equal and Nothing is returned when they are not.

Operations on multi-bindings

elimEmptyMb :: Mb RNil a -> a Source #

Eliminates an empty binding, returning its body. Note that elimEmptyMb is the inverse of emptyMb.

mbCombine :: forall k (c1 :: RList k) (c2 :: RList k) a b. Mb c1 (Mb c2 b) -> Mb (c1 :++: c2) b Source #

Combines a binding inside another binding into a single binding.

mbSeparate :: forall k (ctx1 :: RList k) (ctx2 :: RList k) (any :: k -> *) a. RAssign any ctx2 -> Mb (ctx1 :++: ctx2) a -> Mb ctx1 (Mb ctx2 a) Source #

Separates a binding into two nested bindings. The first argument, of type RAssign any c2, is a "phantom" argument to indicate how the context c should be split.

mbToProxy :: forall k (ctx :: RList k) (a :: *). Mb ctx a -> RAssign Proxy ctx Source #

Returns a proxy object that enumerates all the types in ctx.

mbSwap :: Mb ctx1 (Mb ctx2 a) -> Mb ctx2 (Mb ctx1 a) Source #

Take a multi-binding inside another multi-binding and move the outer binding inside the ineer one.

mbPure :: RAssign f ctx -> a -> Mb ctx a Source #

Put a value inside a multi-binding

mbApply :: Mb ctx (a -> b) -> Mb ctx a -> Mb ctx b Source #

Applies a function in a multi-binding to an argument in a multi-binding that binds the same number and types of names.

mbMap2 :: (a -> b -> c) -> Mb ctx a -> Mb ctx b -> Mb ctx c Source #

Lift a binary function function to Mbs

Eliminators for multi-bindings

nuMultiWithElim :: (RAssign Name ctx -> RAssign Identity args -> b) -> RAssign (Mb ctx) args -> Mb ctx b Source #

asdfasdf

The expression nuWithElimMulti args f takes a sequence args of one or more multi-bindings (it is a runtime error to pass an empty sequence of arguments), each of type Mb ctx ai for the same type context ctx of bound names, and a function f and does the following:

  • Creates a multi-binding that binds names n1,...,nn, one name for each type in ctx;
  • Substitutes the names n1,...,nn for the names bound by each argument in the args sequence, yielding the bodies of the args (using the new name n); and then
  • Passes the sequence n1,...,nn along with the result of substituting into args to the function f, which then returns the value for the newly created binding.

For example, here is an alternate way to implement mbApply:

mbApply' :: Mb ctx (a -> b) -> Mb ctx a -> Mb ctx b
mbApply' f a =
    nuWithElimMulti ('MNil' :>: f :>: a)
                    (\_ ('MNil' :>: 'Identity' f' :>: 'Identity' a') -> f' a')

nuWithElim :: (Name a -> RAssign Identity args -> b) -> RAssign (Mb (RNil :> a)) args -> Binding a b Source #

Similar to nuMultiWithElim but binds only one name. Note that the argument list here is allowed to be empty.

nuMultiWithElim1 :: (RAssign Name ctx -> arg -> b) -> Mb ctx arg -> Mb ctx b Source #

Similar to nuMultiWithElim but takes only one argument

nuWithElim1 :: (Name a -> arg -> b) -> Binding a arg -> Binding a b Source #

Similar to nuMultiWithElim but takes only one argument that binds a single name.

Orphan instances

Functor (Mb ctx) Source # 
Instance details

Methods

fmap :: (a -> b) -> Mb ctx a -> Mb ctx b #

(<$) :: a -> Mb ctx b -> Mb ctx a #

TypeCtx ctx => Applicative (Mb ctx) Source # 
Instance details

Methods

pure :: a -> Mb ctx a #

(<*>) :: Mb ctx (a -> b) -> Mb ctx a -> Mb ctx b #

liftA2 :: (a -> b -> c) -> Mb ctx a -> Mb ctx b -> Mb ctx c #

(*>) :: Mb ctx a -> Mb ctx b -> Mb ctx b #

(<*) :: Mb ctx a -> Mb ctx b -> Mb ctx a #

Show a => Show (Mb c a) Source # 
Instance details

Methods

showsPrec :: Int -> Mb c a -> ShowS #

show :: Mb c a -> String #

showList :: [Mb c a] -> ShowS #