[Haskell-cafe] Library for overloaded indexing (a la (!))

William Yager will.yager at gmail.com
Thu Aug 13 05:18:09 UTC 2015


Hello all,

I put together a small library for the purpose of creating overloaded
indexing operators. The library is available at
https://hackage.haskell.org/package/keyed .

I would like to solicit some advice on the design of this library.

Q1:
The library uses TypeFamilies to determine which types to use for the index
type (which is used to look up a value) and the value type (which is
returned from a lookup).

I originally did this using MultiParamTypeClasses and
FunctionalDependencies, but thought this was cleaner; are there any good
reasons to go back to using FunDeps?

Q2:
Data.Keyed provides pure indexing, while Data.MKeyed provides monadic
indexing (e.g. for mutable vectors or concurrent STM-based maps).

I'm having some trouble with the fact that mutable vectors are keyed on the
PrimState of their corresponding PrimMonad.

Right now, there is a type in the MKeyed class definition called
MContainer. This is the type of the Monad that the lookup operation
returns. I.e.

(!) :: MKeyed d => d -> MKey d -> MContainer d (MValue d)
~
(!) :: IOVector a -> Int -> IO a
or
(!) :: STVector s a -> Int -> ST s a

Unfortunately, this causes an overlap (because both IOVector and STVector
are aliased to MVector).

I tried making an instance for MVector, but the problem is that it's
difficult to actually go from `IOVector a = MVector RealWorld a` to `IO` or
`STVector s a = MVector s a` to `ST`, because neither `IO` nor `ST` appears
in the type of the vector. I can't do

instance (PrimMonad m, s ~ PrimState m) => MKeyed (MVector s a) where ...
    type MContainer (MVector (PrimState m) a) = m

because you can't have type synonyms on the LHS of the type.

I tried bringing `m` into scope using RankNTypes, but that didn't work.

Is there some syntax I can use to bring `m` into scope here?

Or should I be doing this part entirely differently?

Q3:
Is there any way to automatically derive all instances of Keyed for all
types of Data.Vector (using Data.Vector.Generic)? Using `instance Vector v
a => Keyed (v a) where ...` doesn't work, as it overlaps with everything of
the form `(d :: * -> *) (a :: *) :: *`, like `[a]`.

Thanks,
Will
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150812/e8278fc0/attachment-0001.html>


More information about the Haskell-Cafe mailing list