packages feed

abt 0.1.0.0 → 0.1.0.1

raw patch · 9 files changed

+138/−105 lines, 9 filesdep +vinyldep −mtlPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: vinyl

Dependencies removed: mtl

API changes (from Hackage documentation)

- Abt.Tutorial: example :: M [Var]
- Abt.Types.HList: (:*) :: el x -> HList el xs -> HList el (x : xs)
- Abt.Types.HList: Nil :: HList el []
- Abt.Types.HList: data HList :: (κ -> *) -> [κ] -> *
- Abt.Types.HList: hmap :: (forall x. f x -> g x) -> HList f xs -> HList g xs
- Abt.Types.HList: homogenizeA :: Applicative h => (forall x. el x -> h α) -> HList el xs -> h [α]
- Abt.Types.HList: htraverse :: Applicative h => (forall x. f x -> h (g x)) -> HList f xs -> h (HList g xs)
- Abt.Types.HList: instance HEq1 el => HEq1 (HList el)
+ Abt.Class.HEq1: instance HEq1 el => HEq1 (Rec el)
+ Abt.Concrete.LocallyNameless: type Tm0 o = Tm o Z
+ Abt.Tutorial: StepT :: MaybeT m α -> StepT m α
+ Abt.Tutorial: appTm :: M (Tm0 Lang)
+ Abt.Tutorial: eval :: Tm0 Lang -> Tm0 Lang
+ Abt.Tutorial: identityTm :: M (Tm0 Lang)
+ Abt.Tutorial: instance (Monad m, Functor m) => Alternative (StepT m)
+ Abt.Tutorial: instance (Monad m, Functor m) => Applicative (StepT m)
+ Abt.Tutorial: instance Functor m => Functor (StepT m)
+ Abt.Tutorial: instance Monad m => Monad (StepT m)
+ Abt.Tutorial: instance MonadVar Var m => MonadVar Var (StepT m)
+ Abt.Tutorial: main :: IO ()
+ Abt.Tutorial: newtype StepT m α
+ Abt.Tutorial: runStepT :: StepT m α -> MaybeT m α
+ Abt.Tutorial: star :: Monad m => (α -> StepT m α) -> (α -> m α)
+ Abt.Tutorial: step :: Tm0 Lang -> StepT M (Tm0 Lang)
+ Abt.Tutorial: stepsExhausted :: Applicative m => StepT m α
+ Abt.Types.View: type View0 v o φ = View v o Z φ
- Abt.Class.Abt: ($$) :: Abt v o t => o ns -> HList t ns -> t Z
+ Abt.Class.Abt: ($$) :: Abt v o t => o ns -> Rec t ns -> t Z
- Abt.Class.Abt: class (Show1 o, Show v) => Abt (v :: *) (o :: [Nat] -> *) (t :: Nat -> *) | t -> v o, o -> t where var = into . V v \\ e = into $ (v :\ e) o $$ es = into $ o :$ es subst e v e' = do { oe' <- out e'; case oe' of { V v' -> return $ if v == v' then e else e' v' :\ e'' -> do { e''' <- subst e v e''; return $ v' \\ e''' } o :$ es -> do { es' <- htraverse (subst e v) es; return $ o $$ es' } } } xe // e' = do { v :\ e <- out xe; subst e' v e } freeVars e = do { oe <- out e; case oe of { V v -> return [v] v :\ e' -> do { delete v <$> freeVars e' } o :$ es -> do { concat <$> homogenizeA freeVars es } } } toString e = do { vu <- out e; case vu of { V v -> return $ show v v :\ e -> do { e' <- toString e; return $ show v ++ "." ++ e' } o :$ es -> do { es' <- homogenizeA toString es; return $ show1 o ++ "[" ++ intercalate ";" es' ++ "]" } } }
+ Abt.Class.Abt: class (Show1 o, Show v) => Abt (v :: *) (o :: [Nat] -> *) (t :: Nat -> *) | t -> v o where var = into . V v \\ e = into $ v :\ e o $$ es = into $ o :$ es subst e v e' = do { oe' <- out e'; case oe' of { V v' -> return $ if v == v' then e else e' v' :\ e'' -> (v' \\) <$> subst e v e'' o :$ es -> (o $$) <$> subst e v `rtraverse` es } } xe // e' = do { v :\ e <- out xe; subst e' v e } freeVars e = do { oe <- out e; case oe of { V v -> return [v] v :\ e' -> do { delete v <$> freeVars e' } _ :$ es -> fmap concat . sequence . recordToList $ Const . freeVars <<$>> es } } toString e = do { vu <- out e; case vu of { V v -> return $ show v v :\ e' -> do { estr <- toString e'; return $ show v ++ "." ++ estr } o :$ es -> do { es' <- sequence . recordToList $ Const . toString <<$>> es; return $ show1 o ++ "[" ++ intercalate ";" es' ++ "]" } } }
- Abt.Class.Show1: class Show1 f where showsPrec1 i x = (show1 x ++) show1 x = showsPrec1 0 x ""
+ Abt.Class.Show1: class Show1 f where showsPrec1 _ x = (show1 x ++) show1 x = showsPrec1 0 x ""
- Abt.Concrete.LocallyNameless: App :: o ns -> HList (Tm o) ns -> Tm o Z
+ Abt.Concrete.LocallyNameless: App :: o ns -> Rec (Tm o) ns -> Tm0 o
- Abt.Concrete.LocallyNameless: Bound :: Int -> Tm o Z
+ Abt.Concrete.LocallyNameless: Bound :: Int -> Tm0 o
- Abt.Concrete.LocallyNameless: Free :: Var -> Tm o Z
+ Abt.Concrete.LocallyNameless: Free :: Var -> Tm0 o
- Abt.Types.View: (:$) :: o ns -> HList φ ns -> View v o Z φ
+ Abt.Types.View: (:$) :: o ns -> Rec φ ns -> View0 v o φ
- Abt.Types.View: V :: v -> View v o Z φ
+ Abt.Types.View: V :: v -> View0 v o φ

Files

abt.cabal view
@@ -1,15 +1,13 @@ name:                abt-version:             0.1.0.0+version:             0.1.0.1 synopsis:            Abstract binding trees for Haskell description:         A Haskell port of the Carnegie Mellon ABT library (SML), with some improvements. license:             MIT license-file:        LICENSE author:              Jonathan Sterling maintainer:          jon@jonmsterling.com--- copyright: category:            Language build-type:          Simple--- extra-source-files: cabal-version:       >=1.10  library@@ -20,14 +18,12 @@                        Abt.Class.Abt,                        Abt.Types,                        Abt.Types.Nat,-                       Abt.Types.HList,                        Abt.Types.View,                        Abt.Concrete.LocallyNameless                        Abt.Tutorial-  -- other-modules:-  -- other-extensions:   build-depends:       base >=4.7 && <4.8,-                       transformers,-                       mtl+                       vinyl >=0.5,+                       transformers+  ghc-options:         -Wall   hs-source-dirs:      src   default-language:    Haskell2010
src/Abt/Class/Abt.hs view
@@ -10,28 +10,29 @@ ) where  import Abt.Types.Nat-import Abt.Types.HList import Abt.Types.View import Abt.Class.Monad import Abt.Class.Show1 -import Control.Applicative+import Control.Applicative hiding (Const)+import Data.Vinyl+import Data.Vinyl.Functor import qualified Data.List as L  -- | The 'Abt' signature represents mediation between an arbitrary (possibly--- nameless) term representaion, and a first-order one (the 'View'). Based on+-- nameless) term representaion, and a simple one (the 'View'). Based on -- the (effectful) ismorphism @'into' / 'out'@ between representations, many -- operations can be defined generically for arbitrary operator sets, including -- substitution and aggregation of free variables. ---class (Show1 o, Show v) ⇒ Abt (v ∷ *) (o ∷ [Nat] → *) (t ∷ Nat → *) | t → v o, o → t where+class (Show1 o, Show v) ⇒ Abt (v ∷ *) (o ∷ [Nat] → *) (t ∷ Nat → *) | t → v o where   -- | Convert a 'View' into a term.   --   into     ∷ View v o n t     → t n -  -- | Convert a term into a first-order 'View'.+  -- | Convert a term into a simple 'View'.   --   out     ∷ MonadVar v m@@ -51,13 +52,13 @@     ∷ v     → t n     → t (S n)-  v \\ e = into $ (v :\ e)+  v \\ e = into $ v :\ e    -- | Construct an operator term.   --   ($$)     ∷ o ns-    → HList t ns+    → Rec t ns     → t Z   o $$ es = into $ o :$ es   infixl 1 $$@@ -74,12 +75,8 @@     oe' ← out e'     case oe' of       V v' → return $ if v == v' then e else e'-      v' :\ e'' → do-        e''' ← subst e v e''-        return $ v' \\ e'''-      o :$ es → do-        es' ← htraverse (subst e v) es-        return $ o $$ es'+      v' :\ e'' → (v' \\) <$> subst e v e''+      o :$ es → (o $$) <$> subst e v `rtraverse` es    -- | Instantiate the bound variable of an abstraction.   --@@ -105,9 +102,9 @@       v :\ e' → do         L.delete v <$>           freeVars e'-      o :$ es → do-        concat <$>-          homogenizeA freeVars es+      _ :$ es →+        fmap concat . sequence . recordToList $+          Const . freeVars <<$>> es    -- | Render a term into a human-readable string.   --@@ -119,10 +116,10 @@     vu ← out e     case vu of       V v → return $ show v-      v :\ e → do-        e' ← toString e-        return $ show v ++ "." ++ e'+      v :\ e' → do+        estr ← toString e'+        return $ show v ++ "." ++ estr       o :$ es → do-        es' ← homogenizeA toString es+        es' ← sequence . recordToList $ Const . toString <<$>> es         return $ show1 o ++ "[" ++ L.intercalate ";" es' ++ "]" 
src/Abt/Class/HEq1.hs view
@@ -1,11 +1,19 @@+{-# LANGUAGE GADTs #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE UnicodeSyntax #-}  module Abt.Class.HEq1 where +import Data.Vinyl+ -- | Uniform variant of 'Eq' for indexed types. This is different from -- 'Data.Functor.Eq1' in that it is properly kind polymorphic and crucially -- heterogeneous, and it places no constraint on the index. -- class HEq1 f where   (===) ∷ f i → f j → Bool++instance HEq1 el ⇒ HEq1 (Rec el) where+  RNil === RNil = True+  (x :& xs) === (y :& ys) = x === y && xs === ys+  _ === _ = False
src/Abt/Class/Show1.hs view
@@ -8,7 +8,7 @@ -- class Show1 f where   showsPrec1 ∷ Int → f i → ShowS-  showsPrec1 i x = (show1 x ++)+  showsPrec1 _ x = (show1 x ++)    show1 ∷ f i → String   show1 x = showsPrec1 0 x ""
src/Abt/Concrete/LocallyNameless.hs view
@@ -8,13 +8,13 @@  module Abt.Concrete.LocallyNameless ( Tm(..)+, Tm0 , Var(..) , varName , varIndex ) where  import Abt.Types.Nat-import Abt.Types.HList import Abt.Types.View import Abt.Class.HEq1 import Abt.Class.Show1@@ -22,6 +22,7 @@ import Abt.Class.Monad  import Control.Applicative+import Data.Vinyl  -- | A variable is a De Bruijn index, optionally decorated with a display name. data Var@@ -70,14 +71,18 @@   (\j' → Var n j')     <$> i j --- | Locally nameless terms with operators in @o@ at arity @n@.+-- | Locally nameless terms with operators in @o@ at order @n@. -- data Tm (o ∷ [Nat] → *) (n ∷ Nat) where-  Free ∷ Var → Tm o Z-  Bound ∷ Int → Tm o Z+  Free ∷ Var → Tm0 o+  Bound ∷ Int → Tm0 o   Abs ∷ Tm o n → Tm o (S n)-  App ∷ o ns → HList (Tm o) ns → Tm o Z+  App ∷ o ns → Rec (Tm o) ns → Tm0 o +-- | First order terms (i.e. terms not headed by abstractions).+--+type Tm0 o = Tm o Z+ instance HEq1 o ⇒ HEq1 (Tm o) where   Free v1 === Free v2 = v1 == v2   Bound m === Bound n = m == n@@ -93,8 +98,8 @@ shiftVar v n = \case   Free v' → if v == v' then Bound n else Free v'   Bound m → Bound m-  Abs e → Abs (shiftVar v (n + 1) e)-  App p es → App p $ hmap (shiftVar v n) es+  Abs e → Abs $ shiftVar v (n + 1) e+  App p es → App p $ rmap (shiftVar v n) es  addVar   ∷ Var@@ -104,18 +109,18 @@ addVar v n = \case   Free v' → Free v'   Bound m → if m == n then Free v else Bound m-  Abs e → Abs (addVar v (n + 1) e)-  App p es → App p $ hmap (addVar v n) es+  Abs e → Abs $ addVar v (n + 1) e+  App p es → App p $ rmap (addVar v n) es  instance Show1 o ⇒ Abt Var o (Tm o) where   into = \case     V v → Free v-    v :\ e → Abs (shiftVar v 0 e)+    v :\ e → Abs $ shiftVar v 0 e     v :$ es → App v es    out = \case     Free v → return $ V v-    Bound n → fail "bound variable occured in out"+    Bound _ → fail "bound variable occured in out"     Abs e → do       v ← fresh       return $ v :\ addVar v 0 e
src/Abt/Tutorial.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-}@@ -13,8 +14,9 @@ import Abt.Concrete.LocallyNameless  import Control.Applicative-import Control.Monad.Trans import Control.Monad.Trans.State.Strict+import Control.Monad.Trans.Maybe+import Data.Vinyl  -- | We'll start off with a monad in which to manipulate ABTs; we'll need some -- state for fresh variable generation.@@ -59,14 +61,77 @@   Ap === Ap = True   _ === _ = False --- | Check out the source to see this example term: note that number of--- arguments and presence of abstractions is guaranteed by the types.  The--- representation is not scope-safe (i.e. free variables are permitted), but--- that's how we want it.+-- | A monad transformer for small step operational semantics. ---example ∷ M [Var]-example = do+newtype StepT m α+  = StepT+  { runStepT ∷ MaybeT m α+  } deriving (Monad, Functor, Applicative, Alternative)++-- | To indicate that a term is in normal form.+--+stepsExhausted+  ∷ Applicative m+  ⇒ StepT m α+stepsExhausted = StepT . MaybeT $ pure Nothing++instance MonadVar Var m ⇒ MonadVar Var (StepT m) where+  fresh = StepT . MaybeT $ Just <$> fresh+  named str = StepT . MaybeT $ Just <$> named str++-- | A single evaluation step.+--+step+  ∷ Tm0 Lang+  → StepT M (Tm0 Lang)+step tm =+  out tm >>= \case+    Ap :$ m :& n :& RNil →+      out m >>= \case+        Lam :$ xe :& RNil → xe // n+        _ → app <$> step m <*> pure n <|> app <$> pure m <*> step n+          where+            app a b = Ap $$ a :& b :& RNil+    _ → stepsExhausted++-- | The reflexive-transitive closure of a small-step operational semantics.+--+star+  ∷ Monad m+  ⇒ (α → StepT m α)+  → (α → m α)+star f a =+  runMaybeT (runStepT $ f a) >>=+    return a `maybe` star f++-- | Evaluate a term to normal form+--+eval ∷ Tm0 Lang → Tm0 Lang+eval = runM . star step++-- | @λx.x@+--+identityTm ∷ M (Tm0 Lang)+identityTm = do   x ← fresh-  y ← fresh-  let tm = Lam $$ x \\ (Ap $$ var x :* var y :* Nil) :* Nil-  freeVars tm+  return $ Lam $$ (x \\ var x) :& RNil++-- | @(λx.x)(λx.x)@+--+appTm ∷ M (Tm0 Lang)+appTm = do+  tm ← identityTm+  return $ Ap $$ tm :& tm :& RNil++-- | A demonstration of evaluating (and pretty-printing). Output:+--+-- @+-- ap[lam[\@2.\@2];lam[\@3.\@3]] ~>* lam[\@2.\@2]+-- @+--+main ∷ IO ()+main = do+  let mm = runM $ appTm >>= toString+      mm' = runM $ appTm >>= toString . eval+  print $ mm ++ " ~>* " ++ mm'+
src/Abt/Types.hs view
@@ -2,10 +2,8 @@ -- module Abt.Types ( module Abt.Types.Nat-, module Abt.Types.HList , module Abt.Types.View ) where  import Abt.Types.Nat-import Abt.Types.HList import Abt.Types.View
− src/Abt/Types/HList.hs
@@ -1,43 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UnicodeSyntax #-}--module Abt.Types.HList-( HList(..)-, hmap-, htraverse-, homogenizeA-) where--import Control.Applicative-import Abt.Class.HEq1--data HList ∷ (κ → *) → [κ] → * where-  Nil ∷ HList el '[]-  (:*) ∷ el x → HList el xs → HList el (x ': xs)-infixr 8 :*--hmap ∷ (∀ x. f x → g x) → HList f xs → HList g xs-hmap η = \case-  Nil → Nil-  x :* xs → η x :* hmap η xs--htraverse ∷ Applicative h ⇒ (∀ x. f x → h (g x)) → HList f xs → h (HList g xs)-htraverse η = \case-  Nil → pure Nil-  x :* xs → (:*) <$> η x <*> htraverse η xs--homogenizeA ∷ Applicative h ⇒ (∀ x. el x → h α) → HList el xs → h [α]-homogenizeA η = \case-  Nil → pure []-  x :* xs → (:) <$> η x <*> homogenizeA η xs--instance HEq1 el ⇒ HEq1 (HList el) where-  Nil === Nil = True-  (x :* xs) === (y :* ys) = x === y && xs === ys-  _ === _ = False-
src/Abt/Types/View.hs view
@@ -7,29 +7,36 @@  module Abt.Types.View ( View(..)+, View0 , mapView ) where  import Abt.Types.Nat-import Abt.Types.HList+import Data.Vinyl  -- | @v@ is the type of variables; @o@ is the type of operators parameterized--- by arities; @n@ is the "higher type" of the term (i.e. a term has @n=0@, a--- single binding has @n=1@, etc.); @φ@ is the functor which interprets the--- inner structure of the view.+-- by arities; @n@ is the "higher type"/order of the term (i.e. a term has+-- @n=0@, a single binding has @n=1@, etc.); @φ@ is the functor which+-- interprets the inner structure of the view. -- data View (v ∷ *) (o ∷ [Nat] → *) (n ∷ Nat) (φ ∷ Nat → *) where-  V ∷ v → View v o Z φ+  V ∷ v → View0 v o φ   (:\) ∷ v → φ n → View v o (S n) φ-  (:$) ∷ o ns → HList φ ns → View v o Z φ+  (:$) ∷ o ns → Rec φ ns → View0 v o φ +infixl 2 :$++-- | First order term views.+--+type View0 v o φ = View v o Z φ+ -- | Views are a (higher) functor. -- mapView   ∷ (∀ j. φ j → ψ j) -- ^ a natural transformation @φ → ψ@   → View v o n φ -- ^ a view at @φ@   → View v o n ψ-mapView eta = \case+mapView η = \case   V v → V v-  v :\ e → v :\ eta e-  o :$ es → o :$ hmap eta es+  v :\ e → v :\ η e+  o :$ es → o :$ rmap η es