In a least-significant-first bit-serial comparator, the new pair has higher significance than every pair already processed. Equal new bits preserve the earlier result; unequal new bits decide the new result regardless of earlier bits. Use a left fold starting at equality:
type Bit = Int
data LEG = Lt | Eq | Gt deriving (Eq, Show)
step :: LEG -> (Bit,Bit) -> LEG
step old (a,b)
| a < b = Lt
| a > b = Gt
| otherwise = old
compare :: [Bit] -> [Bit] -> LEG
compare as bs = foldl step Eq (pairs as bs)
where
pairs [] [] = []
pairs (a:as) [] = (a,0) : pairs as []
pairs [] (b:bs) = (0,b) : pairs [] bs
pairs (a:as) (b:bs) = (a,b) : pairs as bsInputs have the precondition that each
Bit is 0 or 1. Equal-length inputs are the physical circuit case; pairs also gives a defined unsigned meaning to unequal lengths by padding the shorter input with high-order zeros. Ordinary zip would silently discard significant unmatched bits.After pairs the fold accumulator compares and . Equal new bits add the same amount. If , the new difference has magnitude , exceeding the maximum magnitude of the earlier difference. This proves the accumulator invariant and givesFor the four pairs in the source, the states are
Lt, Gt, Gt, Lt, so the final result compares correctly.