simplify :: Expr SomePrim (Type s) a -> Either String (MP s a)
simplify (Var a) = pure (MPApp (MPVar a))
simplify (Prim (SomePrim p)) = simplifyPrim0 p
simplify (Lam _ _) = throwError "Non-applied lambda abstraction"
simplify (Let (TyScalar s) e b) = mpLet s <$> simplify e <*> transverseScope simplify b
simplify (Let (_ :-> _) e b) = simplify (instantiate1 e b)
simplify (App f x) = case whnf f of
Lam _ b -> simplify (instantiate1 x b)
Prim (SomePrim p) -> simplifyPrim1 p x
App (Prim (SomePrim p)) y -> simplifyPrim2 p y x
_ -> throwError $ "Non-primitive application"
-- ...
simplifyPrim2 :: forall arity s a. IArity arity
=> Prim arity
-> Expr SomePrim (Type s) a
-> Expr SomePrim (Type s) a
-> Either String (MP s a)
simplifyPrim2 p x y = case iarity :: SArity arity of
Arity0 -> throwError $ "Application of 0-arity primitive: " ++ show p
Arity1 -> throwError $ "Over-application of 1-arity primitive: " ++ show p
Arity2 -> (\x' y' -> floatTop (MPApp2 p (pure x') (pure y')))
<$> simplify x
<*> simplify y
TODO: Look at when on laptop
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://pdfs.semanticscholar.org/bc0d/09a0807399cf0a8f3c1f3c37063bfb45fa9f.pdf
The data type STM implements data constructors for all STM-operations, where continuations
corresponding to the
>>=
-operator for sequencing are packed into the constructors.The STM-operations generate the corresponding data, and the monad instance for the type
STM is implemented straightforward, where the bind-operator
>>=
combines the actions: