\begin{code}
module FastBool (
+ --fastBool could be called bBox; isFastTrue, bUnbox; but they're not
FastBool, fastBool, isFastTrue, fastOr, fastAnd
) where
-- Import the beggars
import GHC.Exts
- ( Int(..), Int#, (+#), (-#), (*#),
- quotInt#, negateInt#, (==#), (<#), (<=#), (>=#), (>#)
- )
+#ifdef DEBUG
import Panic
+#endif
type FastBool = Int#
fastBool True = 1#
fastBool False = 0#
-isFastTrue x = x ==# 1#
+
+#ifdef DEBUG
+--then waste time deciding whether to panic. FastBool should normally
+--be at least as fast as Bool, one would hope...
+
+isFastTrue 1# = True
+isFastTrue 0# = False
+isFastTrue _ = panic "FastTypes: isFastTrue"
-- note that fastOr and fastAnd are strict in both arguments
-- since they are unboxed
fastOr 1# _ = 1#
fastOr 0# x = x
-fastOr _ _ = panic# "FastTypes: fastOr"
+fastOr _ _ = panicFastInt "FastTypes: fastOr"
fastAnd 0# _ = 0#
fastAnd 1# x = x
-fastAnd _ _ = panic# "FastTypes: fastAnd"
+fastAnd _ _ = panicFastInt "FastTypes: fastAnd"
+
+--these "panicFastInt"s (formerly known as "panic#") rely on
+--FastInt = FastBool ( = Int# presumably),
+--haha, true enough when __GLASGOW_HASKELL__. Why can't we have functions
+--that return _|_ be kind-polymorphic ( ?? to be precise ) ?
+
+#else /* ! DEBUG */
+--Isn't comparison to zero sometimes faster on CPUs than comparison to 1?
+-- (since using Int# as _synonym_ fails to guarantee that it will
+-- only take on values of 0 and 1)
+isFastTrue 0# = False
+isFastTrue _ = True
+
+-- note that fastOr and fastAnd are strict in both arguments
+-- since they are unboxed
+-- Also, to avoid incomplete-pattern warning
+-- (and avoid wasting time with redundant runtime checks),
+-- we don't pattern-match on both 0# and 1# .
+fastOr 0# x = x
+fastOr _ _ = 1#
+
+fastAnd 0# _ = 0#
+fastAnd _ x = x
+
+#endif /* ! DEBUG */
+
#else /* ! __GLASGOW_HASKELL__ */