[Haskell-cafe] Conceptualizing Functor vs Performance

Yuri Lensky ydl at ydl.cm
Mon Jun 30 05:12:26 UTC 2014


My version of GHC (7.6) didn't have closed type families, but after
upgrading to 7.8.2 it seems with your suggestion I can indeed get halfway
to what I want (having such functionality only be available to pre-selected
types is totally acceptable). I can now write

import qualified Data.Vector.Storable as SV

type family F a where
  F Double = SV.Vector
  F a = []

data T a = T ((F a) a)

instance Functor T where
???

But I still have no idea how to implement Functor. Once again, conceptually
I know that if (F a) == SV.Vector, fmap = SV.map, otherwise fmap = map, but
how can I tell this to Haskell?

Thanks.


On Sun, Jun 29, 2014 at 4:08 AM, John Lato <jwlato at gmail.com> wrote:

> First of all, in your use case are you sure that using Data.Vector is much
> less efficient than one of the specialized types?  It's possible that all
> the allocations are fused away entirely after all.
>
> Secondly, the module Data.Vector.Generic allows you to write functions
> that will work on all types of vectors, including unboxed and
> Storable-based vectors.   Would it be possible to use this module to write
> the desired code?  You'd then need to include a type annotation only once
> at the top level.
>
> Finally, I supposed you could get something like this by creating a class
> similar to Data.Vector.Generic but using closed type families.  I haven't
> worked out the details but I think it would work.  The vector would only be
> available for a pre-defined list of available types though.
>
>
> On Sat, Jun 28, 2014 at 5:37 PM, Yuri Lensky <ydl at ydl.cm> wrote:
>
>> I am having trouble consolidating a performance-based data representation
>> decision I would like to make against the concept of a "functor". The
>> question can be reduced to the following:
>>
>> Conceptually I think that Data.Vector /should/ be a functor. More
>> specifically, I see no CONCEPTUAL reason that it shouldn't be possible to
>> define some "efficient" container-like object (for example for fast Matrix
>> operations for unboxable numbers, but something that still works for a
>> symbolic variable type) that chooses to represent its data as a
>> Data.Vector.Unboxed if possible, but chooses some more generic structure
>> (perhaps a strict list or a generic Data.Vector) if that is not the case. I
>> haven't found such a functor, and can't seem to implement it on my own. The
>> point is that in theory there is no true constraint on the type of the
>> object being contained so it SHOULD be a Functor/Traversable/etc., the
>> representation simply changes to something more efficient only if possible,
>> and decays to a more generic type gracefully if necessary.
>>
>> Perhaps there is some type hackery that can be done with TypeFamilies?
>> I.E. define some container type "data C a = (ListType a) a", but I haven't
>> found a generic way to do this.
>>
>> Finally, I understand that "efficient" data structure can be
>> problem-dependent, but I have no problem defining many different such
>> "generic" types for different applications. The simplest example would be
>> something like (invalid Haskell):
>>
>> (Data.Vector.Unboxed.Vector v a) => data instance (ListType a) = v
>> (Data.Vector.Generic.Vector v a) => data instance (ListType a) = v
>> data instance (ListType a) = ([])
>>
>> Of course implementing fmap is a whole separate issue. The point is I do
>> not think this is the right way/possible, but am wondering what the "true"
>> solution is.
>>
>> Thanks.
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140630/e7a6af00/attachment.html>


More information about the Haskell-Cafe mailing list