/
Num.hs
83 lines (71 loc) · 2.97 KB
/
Num.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{-|
Copyright : (C) 2013-2016, University of Twente
License : BSD2 (see the file LICENSE)
Maintainer : Christiaan Baaij <christiaan.baaij@gmail.com>
-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE Safe #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Clash.Class.Num
( -- * Arithmetic functions for arguments and results of different precision
ExtendingNum (..)
-- * Saturating arithmetic functions
, SaturationMode (..)
, SaturatingNum (..)
, boundedPlus
, boundedMin
, boundedMult
)
where
-- * Arithmetic functions for arguments and results of different precision
-- | Adding, subtracting, and multiplying values of two different (sub-)types.
class ExtendingNum a b where
-- | Type of the result of the addition or subtraction
type AResult a b
-- | Add values of different (sub-)types, return a value of a (sub-)type
-- that is potentially different from either argument.
plus :: a -> b -> AResult a b
-- | Subtract values of different (sub-)types, return a value of a (sub-)type
-- that is potentially different from either argument.
minus :: a -> b -> AResult a b
-- | Type of the result of the multiplication
type MResult a b
-- | Multiply values of different (sub-)types, return a value of a (sub-)type
-- that is potentially different from either argument.
times :: a -> b -> MResult a b
-- * Saturating arithmetic functions
-- | Determine how overflow and underflow are handled by the functions in
-- 'SaturatingNum'
data SaturationMode
= SatWrap -- ^ Wrap around on overflow and underflow
| SatBound -- ^ Become 'maxBound' on overflow, and 'minBound' on underflow
| SatZero -- ^ Become @0@ on overflow and underflow
| SatSymmetric -- ^ Become 'maxBound' on overflow, and (@'minBound' + 1@) on
-- underflow for signed numbers, and 'minBound' for unsigned
-- numbers.
deriving Eq
-- | 'Num' operators in which overflow and underflow behaviour can be specified
-- using 'SaturationMode'.
class (Bounded a, Num a) => SaturatingNum a where
-- | Addition with parametrisable over- and underflow behaviour
satPlus :: SaturationMode -> a -> a -> a
-- | Subtraction with parametrisable over- and underflow behaviour
satMin :: SaturationMode -> a -> a -> a
-- | Multiplication with parametrisable over- and underflow behaviour
satMult :: SaturationMode -> a -> a -> a
{-# INLINE boundedPlus #-}
-- | Addition that clips to 'maxBound' on overflow, and 'minBound' on underflow
boundedPlus :: SaturatingNum a => a -> a -> a
boundedPlus = satPlus SatBound
{-# INLINE boundedMin #-}
-- | Subtraction that clips to 'maxBound' on overflow, and 'minBound' on
-- underflow
boundedMin :: SaturatingNum a => a -> a -> a
boundedMin = satMin SatBound
{-# INLINE boundedMult #-}
-- | Multiplication that clips to 'maxBound' on overflow, and 'minBound' on
-- underflow
boundedMult :: SaturatingNum a => a -> a -> a
boundedMult = satMult SatBound