<div dir="ltr">Yeah, session types are worth looking at for specifying the protocol in the type system. A good paper to look at for implementing session types in Haskell is "Haskell Session Types with (Almost) No Class" which gives a nice overview of the idea and presents a design that looks reasonably nice to use.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 5, 2015 at 6:23 AM,  <span dir="ltr"><<a href="mailto:amindfv@gmail.com" target="_blank">amindfv@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
El Mar 5, 2015, a las 5:58, Christopher Done <<a href="mailto:chrisdone@gmail.com">chrisdone@gmail.com</a>> escribió:<br>
<div><div class="h5"><br>
> Right, what you have there is the simplest implementation and it seems<br>
> pretty common to me, for RPC-style services.<br>
><br>
> The only adjustments I like to make is to ensure input and return are<br>
> matched up.<br>
><br>
> Another way I've taken to is e.g. in Fay:<br>
><br>
> data Returns a = Returns<br>
> data Command =<br>
>  Procedure Int Char (Returns (Text,Maybe [Int]))<br>
><br>
> call :: (Returns a -> Command) -> IO a<br>
> call = …<br>
><br>
> produce :: Returns a -> IO a -> IO a<br>
> produce _ m = m<br>
><br>
> handle :: Command -> IO ()<br>
> handle (Procedure i c r) = produce r (procedure i c)<br>
><br>
> Another way I've taken was in e.g. ghc-server was to use a GADT:<br>
><br>
>    data Command a where<br>
>      LoadTarget :: Text -> Command (Producer Msg (SuccessFlag,Integer))<br>
>      Eval :: Text -> Command (Duplex Text Text EvalResult)<br>
>      Ping :: Integer -> Command (Returns Integer)<br>
>      TypeOf :: Text -> Command (Returns Text)<br>
>      LocationAt :: FilePath -> Text -> Int -> Int -> Int -> Int -><br>
> Command (Returns SrcSpan)<br>
>      TypeAt :: FilePath -> Text -> Int -> Int -> Int -> Int -><br>
> Command (Returns Text)<br>
>      UsesAt :: FilePath -> Text -> Int -> Int -> Int -> Int -><br>
> Command (Returns Text)<br>
>      KindOf :: Text -> Command (Returns Text)<br>
>      InfoOf :: Text -> Command (Returns [Text])<br>
>      Set :: Text -> Command (Returns ())<br>
>      PackageConf :: FilePath -> Command (Returns ())<br>
>      SetCurrentDir :: FilePath -> Command (Returns ())<br>
><br>
> My type looks like a pipe or a conduit, but was more involved because<br>
> it was a duplex:<br>
><br>
>    type Duplex i o r = DuplexT IO i o r<br>
>    type Producer o r = Duplex () o r<br>
>    type Returns r = Duplex () () r<br>
>    type Unit = Duplex () () ()<br>
><br>
> But in essence the commands could return a result and/or accept<br>
> incoming input and produce output. E.g. evaluating a line of Haskell<br>
> lets you send/receive stdin/stdout and eventually return a<br>
> success/fail result.<br>
><br>
> I wrote a few lines of TH to do the dispatching code.<br>
><br>
> I've also seen an approach using type-level literals to put strings in<br>
> the types to use dispatching, but I can't remember who wrote it.<br>
><br>
> You can also use e.g. closed type families to express a finite state<br>
> machine that this-must-happen-before-that-state etc. if you really<br>
> want to ensure every state change is valid.<br>
><br>
> It's hard to find links to any of these things I've seen, not sure<br>
> what the keywords are.<br>
<br>
<br>
<br>
</div></div>The search term for this is "session types" -- iirc there's a nice example in spj's paper "fun with type families"<br>
<span class="HOEnZb"><font color="#888888"><br>
Tom<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<br>
<br>
> _______________________________________________<br>
> Haskell-Cafe mailing list<br>
> <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div>