diff --git a/spago.dhall b/spago.dhall index 5001c67..b3791eb 100644 --- a/spago.dhall +++ b/spago.dhall @@ -12,7 +12,14 @@ to generate this file without the comments in this block. -} { name = "logict" , dependencies = - [ "control", "lists", "maybe", "prelude", "transformers", "tuples" ] + [ "control" + , "lists" + , "maybe" + , "prelude" + , "tailrec" + , "transformers" + , "tuples" + ] , packages = ./packages.dhall , sources = [ "src/**/*.purs", "test/**/*.purs" ] } diff --git a/src/Control/Monad/Logic/Trans.purs b/src/Control/Monad/Logic/Trans.purs index 178b47b..c978aab 100644 --- a/src/Control/Monad/Logic/Trans.purs +++ b/src/Control/Monad/Logic/Trans.purs @@ -8,6 +8,7 @@ import Control.MonadPlus (class MonadPlus, class Alternative, class Alt, class P import Control.Monad.Reader.Class (class MonadReader, local, class MonadAsk, ask) import Control.Monad.State.Class (class MonadState, state) import Control.Monad.Trans.Class (class MonadTrans, lift) +import Control.Monad.Rec.Class (class MonadRec, Step(..)) import Data.Functor (map) import Data.Tuple.Nested ((/\)) import Data.List (List(Nil), (:)) @@ -78,3 +79,17 @@ instance MonadState s m => MonadState s (SFKT m) where instance Lazy (SFKT m a) where defer f = SFKT (\sk fk -> unSFKT (f unit) sk fk) + +instance Monad m => MonadRec (SFKT m) where + tailRecM :: forall acc b. (acc -> SFKT m (Step acc b)) -> acc -> SFKT m b + tailRecM f a0 = SFKT \sk fk -> go {sk: sk, fk: fk} a0 + where + go :: forall ans. { sk :: SK (m ans) b, fk :: FK (m ans) } -> acc -> m ans + go r@{sk,fk} an = + let + (SFKT sfktf) = f an + success st fk' = + case st of + Loop an' -> go r an' + Done b -> sk b fk' + in sfktf success fk