Skip to content

Commit

Permalink
Add Finite class
Browse files Browse the repository at this point in the history
  • Loading branch information
kleinreact committed Jan 10, 2025
1 parent e07ea48 commit 9ad2297
Show file tree
Hide file tree
Showing 13 changed files with 1,291 additions and 13 deletions.
1 change: 1 addition & 0 deletions changelog/2024-12-30T13_36_39+01_00_add_finite_class
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ADDED: Added `Clash.Class.Finite.Finite`: a class for types with only finitely many inhabitants. The class can be considered a more hardware-friendly alternative to `Bounded` and `Enum`, utilizing 'Index' instead of `Int` and vectors instead of lists.
6 changes: 5 additions & 1 deletion clash-prelude/clash-prelude.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Maintainer: QBayLogic B.V. <[email protected]>
Copyright: Copyright © 2013-2016, University of Twente,
2016-2017, Myrtle Software Ltd,
2017-2019, QBayLogic B.V., Google Inc.,
2021-2023, QBayLogic B.V.
2021-2025, QBayLogic B.V.
Category: Hardware
Build-type: Simple

Expand Down Expand Up @@ -183,6 +183,10 @@ Library
Clash.Class.Counter.Internal
Clash.Class.Counter.TH
Clash.Class.Exp
Clash.Class.Finite
Clash.Class.Finite.Internal
Clash.Class.Finite.Internal.Dictionaries
Clash.Class.Finite.Internal.TH
Clash.Class.HasDomain
Clash.Class.HasDomain.HasSingleDomain
Clash.Class.HasDomain.HasSpecificDomain
Expand Down
45 changes: 45 additions & 0 deletions clash-prelude/src/Clash/Class/Finite.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{-|
Copyright : (C) 2024-2025, QBayLogic B.V.
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <[email protected]>
The class of types holding only a finite number of elements. The
'Finite' class offers type level access to the number of elements @n@
and defines a total order on the elements via indexing them from @0@
to @n-1@. Therewith, it gives access to the vector of all inhabitants
of the type and allows to iterate over them in order or to map them back
and forth between their associated indices.
The class can be considered as a more hardware-friendly alternative to
'Bounded' and 'Enum', utilizing 'Clash.Sized.Index.Index' instead of
'Int' and vectors instead of lists.
In comparison, 'Finite' is well suited for types holding finitely many
elements, while the 'Enum' class is better suited for types with
infinitely many inhabitants. The type of @'succ', 'pred' :: 'Enum' a
=> a -> a@ clearly reflects this design choice, as it assumes that
every element has a successor and predecessor, which makes perfect
sense for infinite types, but requires finite types to error on
certain inputs. Wrapping behavior is forbidden according to the
documentation of 'Enum' (assuming that finite types usually have a
'Bounded' instance) such that 'Enum' instances must ship partial
functions for most finite types. Similarly, 'Enum' uses 'Int' as the
index type, which creates a natural mismatch between the number of
inhabitants of the index type vs the ones of the indexed type. For
infinite types, on the other hand, this is /"accepted to be ok"/,
because here the practical assumption is that @'Int' ~ 'Integer'@,
i.e., we never enumerate elements that won't fit into an 'Int' anyway,
which is just an efficiency traded off in the end.
-}
module Clash.Class.Finite
( -- * Finite Class
Finite(..)
-- * Extensions
, GenericReverse(..)
, WithUndefined(..)
-- * Deriving Helpers
, FiniteDerive(..)
)
where

import Clash.Class.Finite.Internal
Loading

0 comments on commit 9ad2297

Please sign in to comment.