commit 202de6475c823c0fea357f39546ee1510825dd20
parent 9bbd83c5cb7e70d86876bc5e00fd5bf0e8b5ab6f
Author: Jared Tobin <jared@jtobin.io>
Date: Sat, 29 Nov 2025 08:48:36 +0400
lib: ord for wider
Diffstat:
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/lib/Data/Choice.hs b/lib/Data/Choice.hs
@@ -10,6 +10,7 @@ module Data.Choice (
, true#
, false#
, decide
+ , to_word#
-- * MaybeWord#
, MaybeWord#(..)
@@ -128,10 +129,15 @@ true# _ = case maxBound :: Word of
W# w -> Choice w
{-# INLINE true# #-}
+-- XX this is probably stupid. check
decide :: Choice -> Bool
decide (Choice c) = isTrue# (neWord# c 0##)
{-# INLINE decide #-}
+to_word# :: Choice -> Word#
+to_word# (Choice c) = and# c 1##
+{-# INLINE to_word# #-}
+
-- constant time 'Maybe Word#'
newtype MaybeWord# = MaybeWord# (# Word#, Choice #)
diff --git a/lib/Data/Word/Wider.hs b/lib/Data/Word/Wider.hs
@@ -35,6 +35,12 @@ data Wider = Wider !(# Word#, Word#, Word#, Word# #)
instance Eq Wider where
Wider a == Wider b = C.decide (C.ct_eq_wider# a b)
+instance Ord Wider where
+ compare (Wider a) (Wider b) = case cmp# a b of
+ 1# -> GT
+ 0# -> EQ
+ _ -> LT
+
instance Show Wider where
show (Wider (# a, b, c, d #)) =
"(" <> show (W# a) <> ", " <> show (W# b) <> ", "
@@ -55,6 +61,41 @@ instance Num Wider where
| a == Wider (# 0##, 0##, 0##, 0## #) = 0
| otherwise = 1
+-- ordering -------------------------------------------------------------------
+
+lt#
+ :: (# Word#, Word#, Word#, Word# #)
+ -> (# Word#, Word#, Word#, Word# #)
+ -> C.Choice
+lt# a b =
+ let !(# _, bit #) = sub_b# a b
+ in C.from_word_lsb# bit
+
+gt#
+ :: (# Word#, Word#, Word#, Word# #)
+ -> (# Word#, Word#, Word#, Word# #)
+ -> C.Choice
+gt# a b =
+ let !(# _, bit #) = sub_b# b a
+ in C.from_word_lsb# bit
+
+cmp#
+ :: (# Word#, Word#, Word#, Word# #)
+ -> (# Word#, Word#, Word#, Word# #)
+ -> Int#
+cmp# (# l0, l1, l2, l3 #) (# r0, r1, r2, r3 #) =
+ let !(# w0, b0 #) = L.sub_b# r0 l0 0##
+ !d0 = or# 0## w0
+ !(# w1, b1 #) = L.sub_b# r1 l1 b0
+ !d1 = or# d0 w1
+ !(# w2, b2 #) = L.sub_b# r2 l2 b1
+ !d2 = or# d1 w2
+ !(# w3, b3 #) = L.sub_b# r3 l3 b2
+ !d3 = or# d2 w3
+ !s = (word2Int# (uncheckedShiftL# b3 1#)) -# 1#
+ in (word2Int# (C.to_word# (C.from_word_nonzero# d3))) *# s
+{-# INLINE cmp# #-}
+
-- construction / conversion --------------------------------------------------
-- | Construct a 'Wider' word from four 'Words', provided in