packages feed

signals-0.2.0.1: src/Signal/Compiler/Knot.hs

{-# LANGUAGE RecursiveDo #-}

module Signal.Compiler.Knot (
    Knot
  , Solver
  , tie
  )
where

import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.Fix

--------------------------------------------------------------------------------
-- * Knot Monad
--------------------------------------------------------------------------------

-- | Knot monad transformer
type Knot resolution constraint m = ReaderT resolution (WriterT [constraint] m)

-- | Resolve linking constraints
type Solver resolution constraint = [constraint] -> resolution

-- | Tie the knot using @solve@ to resolve any constraints
tie :: MonadFix m => Solver resolution constraint -> Knot resolution constraint m a -> m (a, resolution)
tie solve knot =
  mdo (a, constraints) <- runWriterT $ runReaderT knot solution
      let solution = solve constraints
      return (a, solution)

--------------------------------------------------------------------------------