Is there a standard abstraction for this request-response type?

arrows, continuations, haskell, haskell-pipes, monads

Solution

It's Free Monad. The idea is that you have a description of instructions for which you can have multiple interpreters like your `eval` function. Free Monad abstracts over the pattern that this task has. For details I recommend this great post.

To adapt your type to `Free` we can do the following:

{-# LANGUAGE DeriveFunctor #-}

import Control.Monad.Free

data Instruction req rsp next =
  Respond rsp |
  Interact req (rsp -> next)
  deriving (Functor)

type S req rsp =
  Free (Instruction req rsp)

respond :: rsp -> S req rsp ()
respond rsp =
  liftF (Respond rsp)

interact :: req -> S req rsp rsp
interact req =
  liftF (Interact req id)

Now, thanks to `Free`, `S req rsp` is a monad, which means that you can now compose your `respond` and `interact` functions using `Monad` API.

There's more to it. The `respond` and `interact` functions could be generated using Template Haskell with the following extra code:

{-# LANGUAGE TemplateHaskell #-}

import Control.Monad.Free.TH

makeFree ''Instruction

Problem

I have the following type: ``` data S req rsp = Done rsp | Next req (rsp -> S req rsp) ``` The idea is to use it as a pure representation for network communication, i.e: ``` ... Next GetUser $ \uid -> Next (Login uid) $ \success -> Done success ``` Which would then be evaluated by some impure function `eval`. Now, what is this (if anything?) It's not a monad, neither an arrow, as far as I can see. It seems to be something between a stream/pipe/automaton/fsm and the continuation monad. This makes me think that there might be a better representation for this type of thing, but what?

Original source