Skip to main content
edited body
Source Link

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowedenabled buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowed buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

Perhaps you could wrap bare Sockets in an auxiliary datatype that enabled buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

added 91 characters in body
Source Link

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowed buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORefIORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowed buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowed buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

added 99 characters in body
Source Link

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowed buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference!.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowed buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference!

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

Perhaps you could wrap bare Sockets in an auxiliary datatype that allowed buffering. Something like:

data BufferedSocket = BufferedSocket [ByteString] Socket

Then you could define your own recv function like

recv :: BufferedSocket -> Int -> IO (BufferedSocket,ByteString)

which looked at the buffer before actually trying to read data from the socket. Note that this version of recv returns a modified copy of the BufferedSocket, because now we carry some state that isn't captured in the mutable Socket reference.

(Perhaps this extra buffer state should be put in a separate mutable reference, an IORef for example. We are already in mutable-land after all.)

We also need a function

putBack :: ByteString -> BufferedSocket -> BufferedSocket

for prepending the data.


Another option could consist in using a streaming library like streaming or streaming-bytestring and build a Stream of ByteStrings out of the Socket. Prepending would consist simply in concatenating a pure Stream that yields the ByteString to the effectful stream that reads from the socket, using >> or *>.

let socketStream' = S.yield someByteStringValue *> socketStream

Note that the old socketStream value should not be reused!

This might have the disadvantage that you lose some control about how many bytes to "physically" read at each step, because typical Streams don't take "feedback" from downstream about the number of bytes to receive next.

added 197 characters in body
Source Link
Loading
Source Link
Loading