
On Sun, Jul 8, 2012 at 3:05 AM, Nicolas Trangez
On Sun, 2012-07-08 at 01:40 +0200, Gábor Lehel wrote:
unsafeXorSSE42 :: (Storable a,
SV.AlignedToAtLeast SV.A16 o1, SV.Alignment o1, SV.AlignedToAtLeast SV.A16 o2, SV.Alignment o2, SV.AlignedToAtLeast SV.A16 o3, SV.Alignment o3) => SV.Vector o1 a -> SV.Vector o2 a -> SV.Vector o3 a
I wonder if you could get that a bit shorter... I suppose you could write:
instance (AlignedToAtLeast n a, AlignedToAtLeast n b) => AlignedToAtLeast n (a, b) instance (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast n c) => AlignedToAtLeast n (a, b, c) ...and so on...
Once again, nifty! And implemented in [1].
though it feels a little strange semantically (relating a tuple to a scalar), but I don't see what harm can come of it. And then you can just write SV.AlignedToAtLeast SV.A16 (o1, o2, o3) in signatures.
You can also make (Alignment n, Alignment a) a superclass constraint of AlignedToAtLeast, and write instances for Alignment inductively on One and Twice, and then you don't have to write Alignment o1 etc. separately either. So the signature would be just:
unsafeXorSSE42 :: (Storable a, SV.AlignedToAtLeast SV.A16 (o1, o2, o3)) => SV.Vector o1 a -> SV.Vector o2 a -> SV.Vector o3 a
which is friendlier.
I implemented the inductive alignment calculation over One and Twice (good idea, and easy to do), but I don't get the thing about superclasses. I've been trying several approaches (including definitions based on forall and other trickery I never used before), but didn't get things to work, at least: the compiler always said I'd need UndecidableInstances, and that sounds scary... Care to elaborate?
All I meant was class (Alignment n, Alignment a) => AlignedToAtLeast n a but I got a bit ahead of myself, because that rules out the instance on tuples. (I suppose you *could* write some kind of Alignment instance for them, taking their minimum or something, but that's getting a bit too subversive for me). The alternative, if you want both Alignment as a superclass and the ability to constrain multiple types at once, is to have the above, remove the instance on tuples, and instead something like: class (AlignedToAtLeast n a, AlignedToAtLeast n b) => AlignedToAtLeast2 n a b instance (AlignedToAtLeast n a, AlignedToAtLeast n b) => AlignedToAtLeast2 n a b class (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast n c) => AlignedToAtLeast3 n a b c instance (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast n c) => AlignedToAtLeast3 n a b c (feel free to think of better names!) unsafeXorSSE42 :: (Storable a, SV.AlignedToAtLeast3 SV.A16 o1 o2 o3) => SV.Vector o1 a -> SV.Vector o2 a -> SV.Vector o3 a That will require UndecidableInstances, but all that means is that GHC can't prove to itself that instance checking will terminate. So you could end up getting the compiler into an infinite loop (or in practice, to exceed its recursion limit). But it doesn't allow anything unsafe to happen at runtime, and there's plenty of perfectly good instances which terminate even if GHC can't prove it.