[Haskell-beginners] grouping functions together

Dimitri DeFigueiredo defigueiredo at ucdavis.edu
Mon Jun 8 21:47:00 UTC 2015


Hello!

I am trying to tie together a group of functions that turn an unreliable 
remote network call into a reliable one. For each different network 
request I make, a specific group of these functions should always work 
together, but their type signatures are quite different. My first 
thought was to put them all in a typeclass:

import Control.Monad

class Reliable1 m req attempt ack failure result where
     getRequests1 :: Monad m =>               m [req]
     mkAttempt1   :: Monad m => req        -> m (Maybe attempt)
     action1      :: Monad m => attempt    -> m (Maybe ack)
     getAcks1     :: Monad m => [attempt]  -> m [ack]
     mkResult1    :: Monad m => req -> ack -> m (Either failure result)
     run1         :: Monad m => req        -> m result

That doesn't work because not all functions use all parameters. For 
example, getAcks1 has no idea of what the final 'result' type parameter 
is. This lead me to my second attempt. Defining a 'service' type with 
the sole purpose of tying them all together. Here's my current attempt:

{-# LANGUAGE MultiParamTypeClasses #-}

import Control.Monad

class Reliable m service where
     getReqs     :: Monad m => service ->               m [req]
     mkAttempt   :: Monad m => service -> req        -> m (Maybe attempt)
     action      :: Monad m => service -> attempt    -> m (Maybe ack)
     getAcks     :: Monad m => service -> [attempt]  -> m [ack]
     mkResult    :: Monad m => service -> req -> ack -> m (Either 
failure result)
     run         :: Monad m => service -> req        -> m result

data RemoteCall = RemoteCall

instance Reliable IO RemoteCall where
     getReqs     = undefined
     mkAttempt   = undefined
     action      = undefined
     getAcks     = undefined
     mkResult    = undefined
     run         = undefined

This works, but I have to explicitly pass the 'service' argument in 
every call.
Can I avoid passing this parameter every time?
Question, is there a better way to do this?
I wanted to have a wrapper to make my remote calls reliable.

Thanks,

Dimitri





More information about the Beginners mailing list