summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2019-08-10 05:38:08 -0400
committerJoe Crayne <joe@jerkface.net>2019-08-10 06:00:29 -0400
commit81b635594934ed0155fbd3bf544deb544627868a (patch)
tree3f8d92eb2c6ac92b0b167101b2cbbc19c8180151
parent05a7df70fcba1f8a78ab072da99ea055149ddb17 (diff)
Specializing Mod: Cache parsed nat value.
Benchmark shows this doesn't seem to gain us much.
-rw-r--r--packages/base/src/Internal/Specialized.hs28
1 files changed, 24 insertions, 4 deletions
diff --git a/packages/base/src/Internal/Specialized.hs b/packages/base/src/Internal/Specialized.hs
index 3738f79..5f89779 100644
--- a/packages/base/src/Internal/Specialized.hs
+++ b/packages/base/src/Internal/Specialized.hs
@@ -10,6 +10,7 @@
10{-# LANGUAGE KindSignatures #-} 10{-# LANGUAGE KindSignatures #-}
11{-# LANGUAGE ViewPatterns #-} 11{-# LANGUAGE ViewPatterns #-}
12{-# LANGUAGE LambdaCase #-} 12{-# LANGUAGE LambdaCase #-}
13{-# LANGUAGE PolyKinds #-}
13module Internal.Specialized 14module Internal.Specialized
14 ( Mod(..) 15 ( Mod(..)
15 , f2i 16 , f2i
@@ -44,8 +45,9 @@ import Data.Coerce
44import Data.Complex 45import Data.Complex
45import Data.Functor 46import Data.Functor
46import Data.Int 47import Data.Int
48import Data.IORef
47import Data.Maybe 49import Data.Maybe
48import Data.Typeable (eqT,Proxy) 50import Data.Typeable (eqT,Proxy(..),cast)
49import Type.Reflection 51import Type.Reflection
50import Foreign.Marshal.Alloc(free,malloc) 52import Foreign.Marshal.Alloc(free,malloc)
51import Foreign.Marshal.Array(newArray,copyArray) 53import Foreign.Marshal.Array(newArray,copyArray)
@@ -114,11 +116,29 @@ idint = IntegralRep id id id id id Nothing
114coerceint :: Coercible t a => IntegralRep t a 116coerceint :: Coercible t a => IntegralRep t a
115coerceint = IntegralRep coerce coerce coerce coerce coerce Nothing 117coerceint = IntegralRep coerce coerce coerce coerce coerce Nothing
116 118
117modint :: forall t n. (Read t, Storable t) => TypeRep n -> IntegralRep t (Mod n t) 119-- This exists to hopefully save me from parsing a string since Type.Reflection
120-- currently has no direct way to extract a Nat value from a TypeRep.
121cachedNat :: IORef SomeNat
122cachedNat = unsafePerformIO $ newIORef (SomeNat (Proxy :: Proxy 3))
123{-# NOINLINE cachedNat #-}
124
125withTypes :: p (a::k) -> q (b::h) -> f a b -> f a b
126withTypes _ _ = id
127
128modint :: forall t n. (Read t, Storable t, Integral t) => TypeRep n -> IntegralRep t (Mod n t)
118modint r = IntegralRep i2f i2fM f2i f2iM unMod (Just n) 129modint r = IntegralRep i2f i2fM f2i f2iM unMod (Just n)
119 where 130 where
120 n = read . show $ r -- XXX: Hack to get nat value from Type.Reflection 131 -- n = withTypeable r $ fromIntegral . natVal $ (undefined :: Proxy n) -- If only..
121 -- n = fromIntegral . natVal $ (undefined :: Proxy n) 132 n = case unsafePerformIO $ readIORef cachedNat of
133 SomeNat c -> withTypeable r $
134 case withTypes c r <$> eqT of
135 Just Refl -> fromIntegral $ natVal c
136 _ -> unsafePerformIO $ do
137 let newnat = read . show $ r -- XXX: Hack to get nat value from Type.Reflection
138 case someNatVal $ fromIntegral newnat of
139 Just somenat -> writeIORef cachedNat somenat
140 _ -> return ()
141 return newnat
122 142
123coercerep :: Coercible s t => IntegralRep s a -> IntegralRep t a 143coercerep :: Coercible s t => IntegralRep s a -> IntegralRep t a
124coercerep = coerce 144coercerep = coerce