
George Pollard schrieb:
Ok, so I have a small idea I'm trying to work on; call it a Prelude-rewrite if you want. For this I want to be able to have the hierarchy Functor → Applicative → Monad.
For Functor, I would like to be able to implement it for a wider variety of types, as there are types which have aren't polymorphic which would also benefit from having an instance. My running example for this set of types is ByteString; the module contains the method:
map ∷ (Word8 → Word8) → ByteString → ByteString
However, we cannot use this for Functor because ByteString isn't polymorphic. To get around this, I devised the following:
Introduce a type family which represents ‘points’ inside the type:
type family Point f ∷ ★
For ByteString we have:
type instance Point ByteString = Word8
For a polymorphic example (lists) we have:
type instance Point [a] = a
I had the same in mind for Data.Set with Ord constraint for elements, StorableVector with Storable constraint for the elements, and Control.Monad.Excepetion.Asynchronous monad with Monoid constraint for the monadic result. I tried to come up with a class hierarchy: http://code.haskell.org/~thielema/category-constrained/src/Control/Constrain... but I encountered the same problem with the Applicative class. Different from what I tried in Applicative.hs I think that the most flexible approach is to convert the ByteString (or Data.Set or StorableVector) to an interim data structure first where you do, say 'liftA3' aka 'zipWith3', then convert back to the real data structure, here ByteString. The interim data structure can be stream-fusion:Data.Stream, i.e. not a real data structure but an algorithm to read from the ByteString.