<div dir="ltr">This seems like a case where you only really need a record, not a typeclass.<br></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jun 8, 2015 at 2:47 PM Dimitri DeFigueiredo <<a href="mailto:defigueiredo@ucdavis.edu">defigueiredo@ucdavis.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br>
<br>
I am trying to tie together a group of functions that turn an unreliable<br>
remote network call into a reliable one. For each different network<br>
request I make, a specific group of these functions should always work<br>
together, but their type signatures are quite different. My first<br>
thought was to put them all in a typeclass:<br>
<br>
import Control.Monad<br>
<br>
class Reliable1 m req attempt ack failure result where<br>
getRequests1 :: Monad m => m [req]<br>
mkAttempt1 :: Monad m => req -> m (Maybe attempt)<br>
action1 :: Monad m => attempt -> m (Maybe ack)<br>
getAcks1 :: Monad m => [attempt] -> m [ack]<br>
mkResult1 :: Monad m => req -> ack -> m (Either failure result)<br>
run1 :: Monad m => req -> m result<br>
<br>
That doesn't work because not all functions use all parameters. For<br>
example, getAcks1 has no idea of what the final 'result' type parameter<br>
is. This lead me to my second attempt. Defining a 'service' type with<br>
the sole purpose of tying them all together. Here's my current attempt:<br>
<br>
{-# LANGUAGE MultiParamTypeClasses #-}<br>
<br>
import Control.Monad<br>
<br>
class Reliable m service where<br>
getReqs :: Monad m => service -> m [req]<br>
mkAttempt :: Monad m => service -> req -> m (Maybe attempt)<br>
action :: Monad m => service -> attempt -> m (Maybe ack)<br>
getAcks :: Monad m => service -> [attempt] -> m [ack]<br>
mkResult :: Monad m => service -> req -> ack -> m (Either<br>
failure result)<br>
run :: Monad m => service -> req -> m result<br>
<br>
data RemoteCall = RemoteCall<br>
<br>
instance Reliable IO RemoteCall where<br>
getReqs = undefined<br>
mkAttempt = undefined<br>
action = undefined<br>
getAcks = undefined<br>
mkResult = undefined<br>
run = undefined<br>
<br>
This works, but I have to explicitly pass the 'service' argument in<br>
every call.<br>
Can I avoid passing this parameter every time?<br>
Question, is there a better way to do this?<br>
I wanted to have a wrapper to make my remote calls reliable.<br>
<br>
Thanks,<br>
<br>
Dimitri<br>
<br>
<br>
<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>