nfrisby / frags

Plugin gonna getcha, row types
0 stars 1 forks source link

Use-Case: Routes #27

Closed nfrisby closed 5 years ago

nfrisby commented 5 years ago

I'm interested in a data type that represents a special kind of traversal.

I think an Iso between the record type and a corresponding Prod (a la Yoko) would enable phrasing this as a stateful monadic traversal where the state is two Prods one: visited and unvisited that both always add-up to the full type.

nfrisby commented 5 years ago

Closing as of ffcb63677030e073ffdc823abb93ea39abf3352b

nfrisby commented 5 years ago
-- | A traversal that visits each factor exactly once in a fixed order.
-- Each visit consists of a request,
-- which the expected given handler will convert to a response.
-- Both requests and replies may depend on the factor's pre-existing \"environment\" value.
-- A request may additionally depend on the replies from previously visited factors.
newtype Route env req m p rsp = MkRoute{
    runRoute ::
        (forall a. env a -> req a -> m (rsp a))
        -- ^ request handler
      ->
        Prod p env
        -- ^ incoming environment
      ->
        m (Prod p rsp)
  }

nilRoute :: Applicative m => Route env req m 'Nil rsp
nilRoute = MkRoute $ \_ _ -> pure nil

extRoute :: _ =>
    (env a -> req a)
  ->
    (env a -> rsp a -> Route env req m p rsp)
  ->
    Route env req m (p :+ a) rsp
extRoute = \mkReq k -> MkRoute $ \visit envsenv -> do
  let
    (envs,env) = ret envsenv
    req = mkReq env
  rsp <- visit env req
  flip ext rsp <$> runRoute (k env rsp) visit envs