I am writing a chat server in haskell. Earlier i had tcp sockets. Now i am moving to WebSockets. I wanted to create a thin wrapper of `NetworkConn` over it.. I am having problem writing `accept` function. 

`acceptReuqest PendingConnection` returns `Connection`

and 

`fst <$> accept Socket` is `Socket`.

So, i tried following ..
Creating `NetworkConn` for `Socket, Connection, PendingConnection`

```
class NetworkConn sock where
  accept :: (NetworkConn myconn) => sock -> IO myconn

instance NetworkConn NS.Socket where
  accept sock    = fst <$> NS.accept sock

instance NetworkConn WS.Connection where
  accept sock    = error "Not allowed"

```

`acceptReuqest PendingConnection` returns `Connection`

```
instance NetworkConn WS.PendingConnection where
  accept sock = WS.acceptRequest sock

```

This gives me error in `NS.Socket` that 

```
Couldn't match type ‘myconn’ with ‘NS.Socket’
      ‘myconn’ is a rigid type variable bound by
               the type signature for
                 acceptC :: NetworkConn myconn => NS.Socket -> IO myconn
               at src/HChat/Network.hs:21:3
    Expected type: IO
                     (myconn, network-2.6.2.1:Network.Socket.Types.SockAddr)
      Actual type: IO
                     (NS.Socket, network-2.6.2.1:Network.Socket.Types.SockAddr)
    Relevant bindings include
      acceptC :: NS.Socket -> IO myconn
        (bound at src/HChat/Network.hs:21:3)
    In the second argument of ‘(<$>)’, namely ‘NS.accept sock’
    In the expression: fst <$> NS.accept sock

```

and

```
Couldn't match type ‘myconn’ with ‘WS.Connection’
      ‘myconn’ is a rigid type variable bound by
               the type signature for
                 acceptC :: NetworkConn myconn => WS.PendingConnection -> IO myconn
               at src/HChat/Network.hs:31:3
    Expected type: IO myconn
      Actual type: IO WS.Connection
    Relevant bindings include
      acceptC :: WS.PendingConnection -> IO myconn
        (bound at src/HChat/Network.hs:31:3)

```

I starting reading about `class` and could not understand why the error is coming.
I guess it is a syntactic error, but unable to figure it out. Please help.

Also Is it possible to restrict the return type to be NetworkConn because i only want to call few methods defined only in NetworkConn.. ?

Trying two classes:

```
class CandidateConn c where
  acceptC :: (NetworkConn s) => c -> IO s

class NetworkConn sock where
  send :: sock -> C.ByteString -> IO ()
  recv :: sock -> IO C.ByteString
  accept :: (CandidateConn conn) => conn -> IO sock

instance NetworkConn NS.Socket where
  send sock text = void $ NSB.send sock text
  recv sock      = NSB.recv sock 1024
  accept c       = acceptC c

instance CandidateConn NS.Socket where
  acceptC sock = fst <$> NS.accept sock

```

gives :

```
Couldn't match type ‘s’ with ‘NS.Socket’
      ‘s’ is a rigid type variable bound by
          the type signature for
            acceptC :: NetworkConn s => NS.Socket -> IO s
          at src/HChat/Network.hs:29:3
    Expected type: IO
                     (s, network-2.6.2.1:Network.Socket.Types.SockAddr)
      Actual type: IO
                     (NS.Socket, network-2.6.2.1:Network.Socket.Types.SockAddr)
    Relevant bindings include
      acceptC :: NS.Socket -> IO s (bound at src/HChat/Network.hs:29:3)

```