On Mon, Oct 22, 2007 at 08:02:20PM +0200, Henrik Tramberend wrote: > Dear Hasekellers, > > I am trying to build some abstractions on top of the module > Control.Concurrent and run into a problem with the type system that I do > not understand. > > In particular, I want to define two classes 'Channel' and 'Port' (see > below) that define a common interface for several concrete implementations > with different synchronization characteristics. > > The following code is a simplified excerpt that demonstrates the problem: > > > module Main where > > import Control.Concurrent.MVar > > > class Channel c where > > port :: Port p => c a -> IO (p a)
This type signature means that 'port' is return type overloaded - it can
return ANY kind of port, and the caller gets to choose. Which I don't
think is what you want.
A possible solution is to hide the nature of the port, and use a record
of functions:
data Port a = Port { put :: a -> IO (), get :: IO a }
class Channel c where
port :: c a -> Port a
Another possible approach, if it is vital for clients to know the nature
of the port:
class Port (PortOf c) => Channel c where
type PortOf c :: * -> *
port :: c a -> PortOf c a
class Port p where
get :: p a -> IO a
put :: p a -> a -> IO ()
(Requires type family extension in GHC 6.8; an equivalent formulation
using the older (2000) functional dependancies is possible)
Stefan
signature.asc
Description: Digital signature
_______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
