[Haskell-cafe] Beginners problem with the type system

Stefan O'Rear stefanor at cox.net
Mon Oct 22 14:16:17 EDT 2007

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)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20071022/f4ca0520/attachment.bin

More information about the Haskell-Cafe mailing list