Haskell incompatibilities in numbers


Over 42 slightly incompatible array types¹ and 10 array interfaces ("type classes")². It's easy to learn to choose the right array type. It's difficult to find a set of libraries which produce and consume the same array type.

At least 6 incompatible bytestring types³. Given two libraries producing or consuming bytestrings, they are likely to use different types (e.g. digest and SHA produce Data.ByteString.Lazy.ByteString, but AES uses Data.ByteString.ByteString; aeson expects Data.ByteString.Lazy.ByteStrings, while utf8-light produces Data.ByteString.ByteString).

At least 3 incompatible plain text types⁴. In the wild, a random bytestring type may be used where plain text type should be exposed in the API (I am looking at you, aeson).

For any performance-sensitive task and data structure, the number of incompatible types tends to proliferate to cover optional mutability, unboxed storage, interoperability with C, etc. Libraries expose their implementation details. Users choose types according to the first library they use, but it's not long before they need to convert types. Some people write unifying type classes to assist type conversion (e.g. bytestring-class, utf8-light), but overall we can hardly see common types or type classes in the public API. It is not a technical problem with Haskell (type classes are great), but that of a social convention (or lack thereof).

More numbers to think about:

At least 10 slightly different regular expression implementations. It took me a day to choose the right one for me (but now I forgot why).

3 XML libraries written in Haskell (not counting bindings). One is slow, one takes an hour to build, one requires to know arrows.

0 (zero) GUI toolkits shipped with Haskell Platform.

¹ Array types: Data.Array.Array, Data.Array.Unboxed.UArray, Data.Array.IO.{IOArray, IOUArray}, Data.Array.IO.Safe.{IOArray, IOUArray}, Data.Array.ST.{STArray, STUArray}, Data.Array.ST.Safe.{STArray, STUArray}, Data.Array.{Storable,Storable.Safe}.StorableArray, bitwise bitvectors Data.Array.BitArray, Data.Array.BitArray.IO.IOBitArray, Data.Array.BitArray.ST.STBitArray, vectors Data.{Vector,Vector.Safe}.{Vector,MVector}, Data.Vector.{Mutable,Mutable.Safe}.MVector, Data.Vector.{Primitive,Primitive.Safe}.{Vector,MVector}, Data.Vector.Primitive.{Mutable,Mutable.Safe}.MVector, Data.Vector.Storable.{Vector,MVector}, Data.Vector.Storable.Mutable.MVector, acceleraged Data.Array.Accelerate.Array, AC-VanillaArrays Data.Array.Vanilla.Unsafe.{IArray,MArray}, diff arrays IOToDiffArray, a whole tree of Data.ArrayBZ arrays parallel to almost every other type of arrays, DPH parallel arrays Data.Array.Parallel.PArray, various repa array representations (Data.Array.Repa.{D,C,U,V,B,F,P,S,I,X}... ² Array interfaces: Data.Array.IArray.IArray, Data.Array.{MArray,MArray.Safe}.MArray, Data.Vector.Generic.Vector, Data.Vector.{Generic,Generic.Safe,Generic.Mutable,Generic.Mutable.Safe}.MVector, Control.Monad.Array.Class.{MonadArray,MonadUArray}. Some of them could be the same, or not? ³ ByteStrings: Data.ByteString.ByteString and Data.ByteString.Lazy.ByteString (using Word8), Data.ByteString.Char8.ByteString and Data.ByteString.Lazy.Char8.ByteString (using Char), UTF8-aware Data.ByteString.UTF8.ByteString and Data.ByteString.Lazy.UTF8.ByteString (using Word8). ⁴ Plain text types: String, Data.Text.Text and Data.Text.Lazy.Text.