{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE DeriveGeneric #-}
module Unbound.Generics.LocallyNameless.Bind (
Bind(..)
) where
import Control.Applicative (Applicative(..), (<$>))
import Control.DeepSeq (NFData(..))
import Data.Monoid ((<>), All(..))
import GHC.Generics (Generic)
import Unbound.Generics.LocallyNameless.Alpha
data Bind p t = B p t
deriving (Generic)
instance (NFData p, NFData t) => NFData (Bind p t) where
rnf (B p t) = rnf p `seq` rnf t `seq` ()
instance (Show p, Show t) => Show (Bind p t) where
showsPrec prec (B p t) =
showParen (prec > 0) (showString "<"
. showsPrec prec p
. showString "> "
. showsPrec 0 t)
instance (Alpha p, Alpha t) => Alpha (Bind p t) where
aeq' ctx (B p1 t1) (B p2 t2) =
aeq' (patternCtx ctx) p1 p2
&& aeq' (incrLevelCtx ctx) t1 t2
fvAny' ctx nfn (B p t) = B <$> fvAny' (patternCtx ctx) nfn p
<*> fvAny' (incrLevelCtx ctx) nfn t
isPat _ = inconsistentDisjointSet
isTerm (B p t) = (All $ isConsistentDisjointSet $ isPat p) <> isTerm t
close ctx b (B p t) =
B (close (patternCtx ctx) b p) (close (incrLevelCtx ctx) b t)
open ctx b (B p t) =
B (open (patternCtx ctx) b p) (open (incrLevelCtx ctx) b t)
nthPatFind b = error $ "Binding " ++ show b ++ " used as a pattern"
namePatFind b = error $ "Binding " ++ show b ++ " used as a pattern"
swaps' ctx perm (B p t) =
B (swaps' (patternCtx ctx) perm p)
(swaps' (incrLevelCtx ctx) perm t)
freshen' ctx (B p t) = do
(p', perm1) <- freshen' (patternCtx ctx) p
(t', perm2) <- freshen' (incrLevelCtx ctx) (swaps' (incrLevelCtx ctx) perm1 t)
return (B p' t', perm1 <> perm2)
{-# INLINE freshen' #-}
lfreshen' ctx (B p t) cont =
lfreshen' (patternCtx ctx) p $ \p' pm1 ->
lfreshen' (incrLevelCtx ctx) (swaps' (incrLevelCtx ctx) pm1 t) $ \t' pm2 ->
cont (B p' t') (pm1 <> pm2)
acompare' ctx (B p1 t1) (B p2 t2) =
acompare' (patternCtx ctx) p1 p2 <> acompare' (incrLevelCtx ctx) t1 t2