Convert between various textual representations.
Convert between various types representing textual data. This library differs from the similar string-conversions library in that this library exports class methods that are monomorphic in their return type. This enhances readability and aids type inference.
text-convert
Convert between various types representing textual data. This library differs from the similar string-conversions
library in that this library exports class methods that are monomorphic in their return type. This enhances readability and aids type inference.
The module Text.Convert
exports seven one-method type classes. The methods are designed to be input-type polymorphic and output-type monomorphic, to aid with readability and type inference. The classes are:
ToString
, with methodasString
;ToByteString
, with methodasByteString
;ToLazyByteString
, with methodasLazyByteString
;ToByteStringBuilder
, with methodasByteStringBuilder
;ToText
, with methodasText
;ToLazyText
, with methodasLazyText
; andToTextBuilder
, with methodasTextBuilder
.
Design goals in order of importance:
- correctness (including totality);
- efficiency; and
- ease of use. The author hopes that the design achieves these goals to a high degree.
To comment on correctness, we are using lenient UTF-8 decoding when converting between ByteString
s and Text
s, which means the conversions are correct in the sense that they are total, but they are incorrect in the sense that they may replace some unicode characters with the usual replacement character. Since this library serves a very general purpose, users will not necessarily place any restrictions on the inputs of these conversion functions, so the author thought that totality was important. Notably, this choice agrees with the behavior of many text editors and readers that use similar decoding strategies.
To comment on efficiency, we avoid unnecessary intermediate conversions where possible. For example, instead of converting Text
to ByteString
through String
(a design admirable in that it is simple, correct, and a quantity of code that is linear in number of supported datatypes), we choose to use a bespoke conversion function for every pair of supported datatypes wherever possible (resulting in a quadratic quantity of code). We also avoid unnecessary allocation. For example, instead of converting LazyByteString
to Text
through LazyText
(an approach that would entail creating a new rope of Text
that would immediately be converted into a single array), we convert LazyByteString
to Text
through ByteString
(which is a single array). We don't have any benchmarks to support this design choice, admittedly, as we consider the cost of creating a benchmark suite overrides the benefits of having one at this time. Should interest in this library grow, we may revisit this decision.