packages feed

Frank-0.1: ElabMonad.lhs

> {-# OPTIONS_GHC -F -pgmF she #-}
> {-# LANGUAGE TypeOperators, KindSignatures, GADTs, TypeSynonymInstances,
>     FlexibleInstances, GeneralizedNewtypeDeriving, TupleSections,
>     MultiParamTypeClasses #-}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

> module ElabMonad where

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

> import Debug.Trace

> import Prelude hiding (elem, all, foldr, concat)
> import Data.Char
> import Data.List hiding (elem, all, foldr, concat)
> import Data.Monoid
> import Data.Foldable
> import Data.Traversable
> import Control.Applicative
> import Control.Monad
> import Control.Newtype
> import Control.Arrow
> import Data.Void

> import Gubbins
> import Types
> import Pa
> import Syntax
> import Template
> import Check



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% Elaboration Monad and ghastly plumbing                             %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

> type GetSigs = () :>>: [Sig]
> type GetInfo = () :>>: TypeInfo
> type GetCx = () :>>: Cx
> type SetCx = Cx :>>: ()

> type ElabM = Free ((Moan :+: (GetCx :+: SetCx)) :+: (GetSigs :+: GetInfo))

> moanE :: TError -> ElabM a
> moanE e = com (L (L (e :? absurd)))

> getCxE :: ElabM Cx
> getCxE = com (L (R (L (() :? Ret))))

> setCxE :: Cx -> ElabM ()
> setCxE g = com (L (R (R (g :? Ret))))

> modCxE :: (Cx -> Cx) -> ElabM ()
> modCxE f = (|setCxE (|f getCxE|) @ |)

> getSigsE :: ElabM [Sig]
> getSigsE = com (R (L (() :? Ret)))

> getInfoE :: ElabM TypeInfo
> getInfoE = com (R (R (() :? Ret)))

 elabUnify :: UnifyM x -> ElabM x
 elabUnify u = case moc u of
   Right x -> Ret x
   Left (L _) -> moanE UnifyFail
   Left (R (L (_ :? k))) -> getCxE >>= (elabUnify . k)
   Left (R (R (g :? k))) -> setCxE g >>= (elabUnify . k)

> ttT :: ElabM TemplateTable
> ttT = do
>     info <- getInfoE
>     (g, _) <- getCxE
>     let tt = templateT info
>     return (tt {ttTemplates =  cxTemps g (ttTemplates tt)})
>   where
>     cxTemps B0                ts  = ts
>     cxTemps (g :< (x ::: _))  ts  = cxTemps g (x : ts)
>     cxTemps (g :< _)          ts  = cxTemps g ts

> cxLocal :: Bwd Entry -> ElabM x -> ElabM x
> cxLocal g c = do
>     modCxE (((`mappend` g) . (:< Semicolon)) *** id)
>     x <- c
>     modCxE (popSemi *** id)
>     return x
>  where
>    popSemi (g :< Semicolon)    = g
>    popSemi (g :< _)            = popSemi g

> withSigs :: [Sig] -> ElabM x -> ElabM x
> withSigs ss c = case moc c of
>   Right x -> Ret x
>   Left (L (L (e :? k))) -> moanE e
>   Left (L (R (L (_ :? k)))) -> getCxE >>= (withSigs ss. k)
>   Left (L (R (R (g :? k)))) -> setCxE g >>= (withSigs ss. k)
>   Left (R (L (() :? k))) -> withSigs ss (k ss)
>   Left (R (R (() :? k))) -> getInfoE >>= (withSigs ss . k)   

> baseInfo :: TypeInfo -> ElabM x -> Either TError x
> baseInfo info = go (B0, 0) where
>   go g c = case moc c of
>     Right x -> Right x
>     Left (L (L (e :? k))) -> Left e
>     Left (L (R (L (_ :? k)))) -> go g (k g)
>     Left (L (R (R (g :? k)))) -> go g (k ())
>     Left (R (L (() :? k))) -> go g (k [Up "" :$ []])  -- the ineffable
>     Left (R (R (() :? k))) -> go g (k info)

> err :: (TError -> TError) -> ElabM x -> ElabM x
> err f c = case moc c of
>   Right x -> Ret x
>   Left (L (L (e :? k))) -> moanE $ f e
>   Left (L (R (L (_ :? k)))) -> getCxE >>= (err f . k)
>   Left (L (R (R (g :? k)))) -> setCxE g >>= (err f . k)
>   Left (R (L (() :? k))) -> getSigsE >>= (err f . k)
>   Left (R (R (() :? k))) -> getInfoE >>= (err f . k)   

> hnf :: VT -> ElabM VT
> hnf (Q i) = do
>     (g, _) <- getCxE
>     return $ improve (Q i) g
>   where
>     improve (Q i)  (g :< (j :=? Just v)) | i == j  = improve v g
>     improve (Q i)  (g :< _)                        = improve (Q i) g
>     improve v      _                               = v
> hnf v = (|v|)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% Datatypes for contexts                                             %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

> data Entry
>   = Semicolon
>   | Int :=? Maybe VT
>   | Template ::: (Int, VT)
>   deriving Show

> type Cx = (Bwd Entry, Int)  -- a context and a nonce

> instance TMang Entry where
>   tMang s Semicolon = (|Semicolon|)
>   tMang s (q :=? mv) = (| ~q :=? tMang s mv|)
>   tMang s (x ::: iv) = (| ~x ::: tMang s' iv|) where
>     s' (VX i) = pure (X i)
>     s' v = s v

> withTopEntry :: (Entry -> ElabM (Bwd Entry)) -> ElabM ()
> withTopEntry f = getCxE >>= \ (g, i) -> case g of
>   B0      -> moanE $ Cockup "fell off the bottom of the context"
>   g :< e  -> do
>     setCxE (g, i)
>     h <- f e
>     modCxE ((`mappend` h) *** id)