Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert TextIO stream into BinIO stream in Standard ML

Tags:

sml

In Standard ML, I have a function that writes to BinIO.outstream and I would like it to write to the standard output.

While TextIO structure has stdOut of TextIO.outstream type, BinIO has no such variable, and TexIO.outstream is not compatible with BinIO.outstream:

- f;
val it = fn : BinIO.outstream -> unit
- TextIO.stdOut;
val it = - : TextIO.outstream
- f TextIO.stdOut;
stdIn:6.1-6.16 Error: operator and operand don't agree [tycon mismatch]
  operator domain: BinIO.outstream
  operand:         TextIO.outstream
  in expression:
    f TextIO.stdOut

Now what is easiest way to convert TextIO.outstream into BinIO.outstream? i.e. how to implement ??? below?

- f (??? TextIO.stdOut);

Update:

For those who are interested, here is an implementation in accordance with Andreas' answer:

fun textWriterToBinWriter (TextPrimIO.WR { name,
                                           chunkSize,
                                           writeVec,
                                           writeArr,
                                           writeVecNB,
                                           writeArrNB,
                                           block,
                                           canOutput,
                                           getPos,
                                           setPos,
                                           endPos,
                                           verifyPos,
                                           close,
                                           ioDesc }) =
      let
        fun convertWriteVec textWriteVec =
            textWriteVec o CharVectorSlice.full o Byte.unpackStringVec
        fun convertWriteArr textWriteArr =
            textWriteArr o CharArraySlice.full o CharArray.fromList o explode o Byte.unpackString
      in
        BinPrimIO.WR {
          name = name,
          chunkSize = chunkSize,
          writeVec = Option.map convertWriteVec writeVec,
          writeArr = Option.map convertWriteArr writeArr,
          writeVecNB = Option.map convertWriteVec writeVecNB,
          writeArrNB = Option.map convertWriteArr writeArrNB,
          block = block,
          canOutput = canOutput,
          getPos = getPos,
          setPos = setPos,
          endPos = endPos,
          verifyPos = verifyPos,
          close = close,
          ioDesc = ioDesc }
      end

fun textStreamToBinStream' textStream =
      let
        val (textWriter, bufferMode) = TextIO.StreamIO.getWriter textStream
      in
        BinIO.StreamIO.mkOutstream (textWriterToBinWriter textWriter, bufferMode)
      end

fun textStreamToBinStream textStream =
      let
        val textStream' = TextIO.getOutstream textStream
      in
        BinIO.mkOutstream (textStreamToBinStream' textStream')
      end
like image 440
tkob Avatar asked Oct 17 '22 19:10

tkob


1 Answers

In principle, it should be possible to write a TextIO.outstream to BinIO.outstream conversion function (or vice versa), but while relatively mechanical, it requires a bit of work. You need to implement:

  1. using the Byte structure, a conversion function TextPrimIO.writer -> BinPrimIO.writer
  2. using that, a conversion function TextIO.StreamIO.outstream -> BinIO.StreamIO.outstream
  3. using that, a conversion function TextIO.outstream -> BinIO.outstream

However, I doubt it is recommended doing a conversion like that. In particular, OS interfaces and tools typically assume that stdout and friends are, in fact, text streams.

If all you need is to write a Word8 vector, then it should be enough to convert it to string beforehand, e.g. using the Byte structure.

like image 182
Andreas Rossberg Avatar answered Oct 21 '22 08:10

Andreas Rossberg