Last active
          January 11, 2025 15:44 
        
      - 
      
- 
        Save themoritz/189907f2ee41c572554eb67ffda4b130 to your computer and use it in GitHub Desktop. 
Revisions
- 
        themoritz revised this gist Apr 5, 2017 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -42,7 +42,7 @@ coproduct f g = \case L e -> f e R b -> g b -- Product data (f :*: g) r = Pair (f r) (g r) 
- 
        themoritz revised this gist Apr 3, 2017 . 1 changed file with 13 additions and 3 deletions.There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,7 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-} module Indexed where -- Natural transformation.. infixr 5 ~> @@ -24,7 +24,7 @@ newtype K a b = K { getK :: a } deriving (Functor) -- Indexed functors class IxFunctor (f :: (k -> *) -> k -> *) where imap :: (a ~> b) -> (f a ~> f b) -- Indexed coproduct @@ -42,6 +42,10 @@ coproduct f g = \case L e -> f e R b -> g b -- Indexed product data (f :*: g) r = Pair (f r) (g r) -- Indexed fixed point newtype IxFix f i = Fix { unfix :: f (IxFix f) i } @@ -59,6 +63,12 @@ ana coalg = Fix . imap (ana coalg) . coalg ana' :: IxFunctor f => (a .~> f (K a)) -> (a .~> IxFix f) ana' coalg = ana (coalg . getK) . K para :: IxFunctor f => (f (IxFix f :*: a) ~> a) -> (IxFix f ~> a) para alg = alg . imap (\r -> Pair r (para alg r)) . unfix para' :: IxFunctor f => (f (IxFix f :*: (K a)) ~>. a) -> (IxFix f ~>. a) para' alg = alg . imap (\r -> Pair r (para (K . alg) r)) . unfix -- AST ------------------------------------------------------------------------- data AstIx = Expr | Binder @@ -107,4 +117,4 @@ pretty = cata' (coproduct goExpr goBinder) -------------------------------------------------------------------------------- main :: IO () main = putStrLn $ pretty exampleAst 
- 
        themoritz created this gist Mar 31, 2017 .There are no files selected for viewingThis file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,110 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-} module IxFix where -- Natural transformation.. infixr 5 ~> type f ~> g = forall i. f i -> g i -- .. with constant on the left infixr 5 .~> type f .~> g = forall i. f -> g i -- .. with constant on the right infixr 5 ~>. type f ~>. g = forall i. f i -> g -- Constant functor newtype K a b = K { getK :: a } deriving (Functor) -- Indexed functors class IxFunctor (f :: (k -> *) -> (k -> *)) where imap :: (a ~> b) -> (f a ~> f b) -- Indexed coproduct data (f :+: g) (r :: k -> *) (ix :: k) = L (f r ix) | R (g r ix) instance (IxFunctor f, IxFunctor g) => IxFunctor (f :+: g) where imap f = \case L x -> L (imap f x) R x -> R (imap f x) coproduct :: (f r ix -> a) -> (g r ix -> a) -> (f :+: g) r ix -> a coproduct f g = \case L e -> f e R b -> g b -- Indexed fixed point newtype IxFix f i = Fix { unfix :: f (IxFix f) i } -- Recursion Schemes ----------------------------------------------------------- cata :: IxFunctor f => (f a ~> a) -> (IxFix f ~> a) cata alg = alg . imap (cata alg) . unfix cata' :: IxFunctor f => (f (K a) ~>. a) -> (IxFix f ~>. a) cata' alg = getK . cata (K . alg) ana :: IxFunctor f => (a ~> f a) -> (a ~> IxFix f) ana coalg = Fix . imap (ana coalg) . coalg ana' :: IxFunctor f => (a .~> f (K a)) -> (a .~> IxFix f) ana' coalg = ana (coalg . getK) . K -- AST ------------------------------------------------------------------------- data AstIx = Expr | Binder data ExprF (r :: AstIx -> *) (ix :: AstIx) where Var :: String -> ExprF r 'Expr Abs :: r 'Binder -> r 'Expr -> ExprF r 'Expr instance IxFunctor ExprF where imap f = \case Var t -> Var t Abs binder a -> Abs (f binder) (f a) data BinderF (r :: AstIx -> *) (ix :: AstIx) where VarBinder :: String -> BinderF r 'Binder ConstructorBinder :: String -> [r 'Binder] -> BinderF r 'Binder instance IxFunctor BinderF where imap f = \case VarBinder t -> VarBinder t ConstructorBinder t bs -> ConstructorBinder t (map f bs) type Ast = IxFix (ExprF :+: BinderF) -- Usage ----------------------------------------------------------------------- exampleAst :: Ast 'Expr exampleAst = Fix $ L $ Abs constrBinder var where var = Fix $ L $ Var "baz" constrBinder = Fix $ R $ ConstructorBinder "bar" [binder] binder = Fix $ R $ VarBinder "foo" pretty :: Ast i -> String pretty = cata' (coproduct goExpr goBinder) where goExpr :: ExprF (K String) ~>. String goExpr = \case Var t -> t Abs (K b) (K e) -> "\\" ++ b ++ " -> " ++ e goBinder :: BinderF (K String) ~>. String goBinder = \case VarBinder t -> t ConstructorBinder t bs -> t ++ mconcat (map ((" " ++ ) . getK) bs) -------------------------------------------------------------------------------- main :: IO () main = putStrLn $ pretty exampleAst