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?