-- Utility Lenses --------------------------------------------------------------

-- NOTE: successive uses of 'bit' with 'set' will cause terms like this to build
-- up:
--
-- > or# (or# .. (or# val (__word m1)) .. (__word mi)) (__word mj)
--
-- This can be fixed with a rewrite rule that associates all uses of or# to the
-- right, but this seems like it might block other simplifications that would
-- have fired if it was associated to the left.
--
-- The real problem here is that GHC isn't reorganizing the uses of or# to group
-- together constants, which would allow only one final use of or# after
-- simplification.
bit :: B.Bits a => Int -> Lens' a Bool
bit n = lens get upd
  where
  get a       = B.testBit a n

  upd a True  = B.setBit   a n
  upd a False = B.clearBit a n
bit :: B.Bits a => Int -> Lens' a Bool
bit n = lens get upd
  where
  get a       = B.testBit a n

  upd a True  = B.setBit   a n
  upd a False = B.clearBit a n
bit n = lens get upd
  where
  get a       = B.testBit a n

  upd a True  = B.setBit   a n
  upd a False = B.clearBit a n