@@ -113,7 +113,10 @@ import Control.Applicative
113113import Control.Monad
114114#endif
115115
116+ #if __GLASGOW_HASKELL__ < 800
116117import Data.Bits
118+ import Data.Word
119+ #endif
117120
118121#if __GLASGOW_HASKELL__ < 710
119122import Data.Foldable
@@ -127,7 +130,6 @@ import Data.Traversable
127130#endif
128131
129132import Data.Typeable
130- import Data.Word
131133import Foreign.Ptr
132134import Foreign.StablePtr
133135
@@ -432,7 +434,38 @@ subProxy _ _ = error "Exp.(-): undefined"
432434-- * Typeable Reflection
433435--------------------------------------------------------------------------------
434436
437+ stablePtrToIntPtr :: StablePtr a -> IntPtr
438+ stablePtrToIntPtr = ptrToIntPtr . castStablePtrToPtr
439+ {-# INLINE stablePtrToIntPtr #-}
440+
441+ intPtrToStablePtr :: IntPtr -> StablePtr a
442+ intPtrToStablePtr = castPtrToStablePtr . intPtrToPtr
443+ {-# INLINE intPtrToStablePtr #-}
444+
445+
446+ #if __GLASGOW_HASKELL__ >= 800
447+ -- This implementation doesn't work before 8.0 because KnownNat didn't
448+ -- imply Typeable until then.
449+ reifyTypeable :: Typeable a => a -> (forall (s :: * ). (Typeable s , Reifies s a ) => Proxy s -> r ) -> r
450+ # if MIN_VERSION_base(4,4,0)
451+ reifyTypeable (a :: a ) k = unsafeDupablePerformIO $ do
452+ # else
453+ reifyTypeable (a :: a ) k = unsafePerformIO $ do
454+ # endif
455+ p <- newStablePtr a
456+ let n = stablePtrToIntPtr p
457+ reifyNat (fromIntegral n) (\ (_ :: Proxy n ) ->
458+ pure $ k (Proxy :: Proxy (Stable n a )))
435459
460+ data Stable (n :: Nat ) a
461+ instance KnownNat n => Reifies (Stable n a ) a where
462+ reflect = r where
463+ r = unsafePerformIO $ const <$> deRefStablePtr p <* freeStablePtr p
464+ p = intPtrToStablePtr $ fromIntegral $ reflect (Proxy :: Proxy n )
465+ {-# NOINLINE reflect #-}
466+
467+ #else
468+ -- We are in a world of pain
436469class Typeable s => B s where
437470 reflectByte :: proxy s -> IntPtr
438471
@@ -492,14 +525,6 @@ stable :: p b0 -> p b1 -> p b2 -> p b3 -> p b4 -> p b5 -> p b6 -> p b7
492525stable _ _ _ _ _ _ _ _ = Proxy
493526{-# INLINE stable #-}
494527
495- stablePtrToIntPtr :: StablePtr a -> IntPtr
496- stablePtrToIntPtr = ptrToIntPtr . castStablePtrToPtr
497- {-# INLINE stablePtrToIntPtr #-}
498-
499- intPtrToStablePtr :: IntPtr -> StablePtr a
500- intPtrToStablePtr = castPtrToStablePtr . intPtrToPtr
501- {-# INLINE intPtrToStablePtr #-}
502-
503528byte0 :: p (Stable (W b0 b1 b2 b3 ) w1 a ) -> Proxy b0
504529byte0 _ = Proxy
505530
@@ -570,6 +595,7 @@ reifyTypeable a k = unsafePerformIO $ do
570595 reifyByte (fromIntegral (n `shiftR` 56 )) (\ s7 ->
571596 reflectBefore (fmap return k) $
572597 stable s0 s1 s2 s3 s4 s5 s6 s7))))))))
598+ #endif
573599
574600
575601data ReifiedMonoid a = ReifiedMonoid { reifiedMappend :: a -> a -> a , reifiedMempty :: a }
0 commit comments