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

William Yager will.yager at gmail.com
Fri Aug 14 05:31:53 UTC 2015

Thanks! Looks like they're doing it much the same way.

However, the purpose of this was for syntactic simplicity, which I think
it's hard to argue Lens provides in this case. "^? ix" isn't exactly
user-friendly, and it only provides a substitute for "!?", not "!". (Or at
least, I couldn't figure out how to get "!" behavior cleanly.)

The idea here is that you might want some sort of universal, simple
indexing syntax like brackets in other languages, particularly if you have
lots of different indexed structures in your module. It can be annoying to
have to index Seq, Map, etc. in the same scope.


On Thu, Aug 13, 2015 at 3:04 AM, Patrick Chilton <chpatrick at gmail.com>

> FWIW lens has a bit more powerful implementation of Data.Keyed:
> https://hackage.haskell.org/package/lens-4.12.3/docs/Control-Lens-At.html#t:Ixed
> On Thu, Aug 13, 2015 at 7:18 AM, William Yager <will.yager at gmail.com>
> wrote:
>> 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
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150813/1e7fe051/attachment.html>

More information about the Haskell-Cafe mailing list