From 8e12798a0560ee68a46d8a7b5b5d2050b3ff5f1e Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Mon, 11 Sep 2017 09:41:46 -0400 Subject: [PATCH] Define a let binding smart constructor using circular programming. --- src/Data/Functor/Binding.hs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Data/Functor/Binding.hs b/src/Data/Functor/Binding.hs index df043b5a7..8154917d0 100644 --- a/src/Data/Functor/Binding.hs +++ b/src/Data/Functor/Binding.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE DerivingStrategies, GADTs, GeneralizedNewtypeDeriving #-} +{-# LANGUAGE DerivingStrategies, GADTs, GeneralizedNewtypeDeriving, NoStrictData #-} module Data.Functor.Binding ( Metavar(..) -- Abstract binding trees @@ -6,6 +6,7 @@ module Data.Functor.Binding , bindings , freeMetavariables , maxBoundMetavariable +, letBind -- Environments , Env(..) , envExtend @@ -48,6 +49,12 @@ foldMaxMap :: (Foldable t, Ord b) => (a -> Maybe b) -> t a -> Maybe b foldMaxMap f = foldr (max . f) Nothing +letBind :: (Foldable syntax, Functor syntax, Corecursive t, Recursive t, Base t ~ BindingF syntax) => t -> (Metavar -> syntax t) -> t +letBind diff f = embed (Let [(n, diff)] body) + where body = f n + n = maybe (Metavar 0) succ (foldMaxMap maxBoundMetavariable body) + + newtype Env a = Env { unEnv :: [(Metavar, a)] } deriving (Eq, Foldable, Functor, Monoid, Ord, Show, Traversable)