Skip to content

Commit 3b755b9

Browse files
authored
Add Counter a => Counter (Vec n a) instance (#2788)
1 parent 5927123 commit 3b755b9

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

clash-prelude/src/Clash/Class/Counter/Internal.hs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Clash.Sized.BitVector (BitVector, Bit)
1414
import Clash.Sized.Index (Index)
1515
import Clash.Sized.Signed (Signed)
1616
import Clash.Sized.Unsigned (Unsigned)
17+
import Clash.Sized.Vector as Vec (Vec, repeat, mapAccumR)
1718

1819
import Data.Bifunctor (bimap)
1920
import Data.Functor.Identity (Identity(..))
@@ -22,11 +23,14 @@ import Data.Word (Word8, Word16, Word32, Word64)
2223
import GHC.TypeLits (KnownNat, type (<=))
2324

2425
-- $setup
26+
-- >>> :m -Prelude
27+
-- >>> import Clash.Prelude
2528
-- >>> import Clash.Class.Counter
2629
-- >>> import Clash.Sized.BitVector (BitVector)
2730
-- >>> import Clash.Sized.Index (Index)
2831
-- >>> import Clash.Sized.Signed (Signed)
2932
-- >>> import Clash.Sized.Unsigned (Unsigned)
33+
-- >>> import Clash.Sized.Vector (Vec(..), iterate)
3034

3135
-- | t'Clash.Class.Counter.Counter' is a class that composes multiple counters
3236
-- into a single one. It is similar to odometers found in olds cars,
@@ -193,3 +197,26 @@ instance (Counter a0, Counter a1) => Counter (a0, a1) where
193197
(overflowA, a1) = countPredOverflow a0
194198

195199
genTupleInstances maxTupleSize
200+
201+
rippleR :: (a -> (Bool, a)) -> Vec n a -> (Bool, Vec n a)
202+
rippleR f = mapAccumR step True
203+
where
204+
step carry x = if carry then f x else (False, x)
205+
206+
-- | Counters on vectors increment from right to left.
207+
--
208+
-- >>> type T = Vec 2 (Index 10)
209+
-- >>> countSucc @T (0 :> 0 :> Nil)
210+
-- 0 :> 1 :> Nil
211+
-- >>> countSucc @T (0 :> 1 :> Nil)
212+
-- 0 :> 2 :> Nil
213+
-- >>> countSucc @T (0 :> 9 :> Nil)
214+
-- 1 :> 0 :> Nil
215+
-- >>> iterate (SNat @5) (countSucc @T) (9 :> 8 :> Nil)
216+
-- (9 :> 8 :> Nil) :> (9 :> 9 :> Nil) :> (0 :> 0 :> Nil) :> (0 :> 1 :> Nil) :> (0 :> 2 :> Nil) :> Nil
217+
instance (Counter a, KnownNat n, 1 <= n) => Counter (Vec n a) where
218+
countMin = Vec.repeat countMin
219+
countMax = Vec.repeat countMax
220+
221+
countSuccOverflow = rippleR countSuccOverflow
222+
countPredOverflow = rippleR countPredOverflow

0 commit comments

Comments
 (0)