Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add partial applicative typeclass functions #2545

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clash-prelude/src/Clash/Explicit/Signal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ module Clash.Explicit.Signal
, testFor
-- * Type classes
-- ** 'Eq'-like
, (.==.), (./=.)
, (.==.), (.==), (==.), (./=.), (./=), (/=.)
-- ** 'Ord'-like
, (.<.), (.<=.), (.>=.), (.>.)
, (.<.), (.<), (<.), (.<=.), (.<=), (<=.), (.>=.), (.>=), (>=.), (.>.), (.>), (>.)
-- * Bisignal functions
, veryUnsafeToBiSignalIn
, readFromBiSignal
Expand Down
4 changes: 2 additions & 2 deletions clash-prelude/src/Clash/Signal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,9 @@ module Clash.Signal
, testFor
-- * Type classes
-- ** 'Eq'-like
, (.==.), (./=.)
, (.==.), (.==), (==.), (./=.), (./=), (/=.)
-- ** 'Ord'-like
, (.<.), (.<=.), (.>=.), (.>.)
, (.<.), (.<), (<.), (.<=.), (.<=), (<=.), (.>=.), (.>=), (>=.), (.>.), (.>), (>.)
-- * Bisignal functions
, veryUnsafeToBiSignalIn
, readFromBiSignal
Expand Down
149 changes: 147 additions & 2 deletions clash-prelude/src/Clash/Signal/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ module Clash.Signal.Internal
, testFor
-- * Type classes
-- ** 'Eq'-like
, (.==.), (./=.)
, (.==.), (.==), (==.), (./=.), (./=), (/=.)
-- ** 'Ord'-like
, (.<.), (.<=.), (.>=.), (.>.)
, (.<.), (.<), (<.), (.<=.), (.<=), (<=.), (.>=.), (.>=), (>=.), (.>.), (.>), (>.)
-- ** 'Functor'
, mapSignal#
-- ** 'Applicative'
Expand Down Expand Up @@ -1436,6 +1436,30 @@ infix 4 .==.
(.==.) :: (Eq a, Applicative f) => f a -> f a -> f Bool
(.==.) = liftA2 (==)

infix 4 .==
-- | The above type is a generalization for:
--
-- @
-- __(.==)__ :: 'Eq' a => 'Clash.Signal.Signal' a -> a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('==') that allows comparing a @'Clash.Signal.Signal' a@ with a
-- constant @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(.==) :: (Eq a, Applicative f) => f a -> a -> f Bool
(.==) a b = fmap (==b) a
Comment on lines +1448 to +1449
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these new functions where only one argument is in a container don't need to be Applicative, only Functor. You hint at this in the implementations already: only fmap is needed to define these functions


infix 4 ==.
-- | The above type is a generalization for:
--
-- @
-- __(==.)__ :: 'Eq' a => a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('==') that allows comparing a @'Clash.Signal.Signal' a@ with a
-- constant @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(==.) :: (Eq a, Applicative f) => a -> f a -> f Bool
(==.) a b = fmap (a==) b

infix 4 ./=.
-- | The above type is a generalization for:
--
Expand All @@ -1447,6 +1471,31 @@ infix 4 ./=.
(./=.) :: (Eq a, Applicative f) => f a -> f a -> f Bool
(./=.) = liftA2 (/=)

infix 4 ./=
-- | The above type is a generalization for:
--
-- @
-- __(./=)__ :: 'Eq' a => 'Clash.Signal.Signal' a -> a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('/=') that allows comparing a @'Clash.Signal.Signal' a@ with a
-- constant @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(./=) :: (Eq a, Applicative f) => f a -> a -> f Bool
(./=) a b = fmap (/=b) a

infix 4 /=.
-- | The above type is a generalization for:
--
-- @
-- __(/=.)__ :: 'Eq' a => a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('/=') that allows comparing a @'Clash.Signal.Signal' a@ with a
-- constant @a@ and returns a 'Clash.Signal.Signal' of 'Bool'

(/=.) :: (Eq a, Applicative f) => a -> f a -> f Bool
(/=.) a b = fmap (a /=) b

infix 4 .<.
-- | The above type is a generalization for:
--
Expand All @@ -1458,6 +1507,30 @@ infix 4 .<.
(.<.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
(.<.) = liftA2 (<)

infix 4 <.
-- | The above type is a generalization for:
--
-- @
-- __(<.)__ :: 'Ord' a => a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('<') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(<.) :: (Ord a, Applicative f) => a -> f a -> f Bool
(<.) a b = fmap (a<) b

infix 4 .<
-- | The above type is a generalization for:
--
-- @
-- __(.<)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('<') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(.<) :: (Ord a, Applicative f) => f a -> a -> f Bool
(.<) a b = fmap (<b) a

infix 4 .<=.
-- | The above type is a generalization for:
--
Expand All @@ -1469,6 +1542,30 @@ infix 4 .<=.
(.<=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
(.<=.) = liftA2 (<=)

infix 4 .<=
-- | The above type is a generalization for:
--
-- @
-- __(.<=)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('GHC.TypeNats.<=') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(.<=) :: (Ord a, Applicative f) => f a -> a -> f Bool
(.<=) a b = fmap (<=b) a

infix 4 <=.
-- | The above type is a generalization for:
--
-- @
-- __(<=.)__ :: 'Ord' a => a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('GHC.TypeNats.<=') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(<=.) :: (Ord a, Applicative f) => a -> f a -> f Bool
(<=.) a b = fmap (a<=)b

infix 4 .>.
-- | The above type is a generalization for:
--
Expand All @@ -1480,6 +1577,30 @@ infix 4 .>.
(.>.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
(.>.) = liftA2 (>)

infix 4 .>
-- | The above type is a generalization for:
--
-- @
-- __(.>)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('>') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(.>) :: (Ord a, Applicative f) => f a -> a -> f Bool
(.>) a b = fmap (>b) a

infix 4 >.
-- | The above type is a generalization for:
--
-- @
-- __(>.)__ :: 'Ord' a => a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('>') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(>.) :: (Ord a, Applicative f) => a -> f a -> f Bool
(>.) a b = fmap (a>) b

infix 4 .>=.
-- | The above type is a generalization for:
--
Expand All @@ -1491,6 +1612,30 @@ infix 4 .>=.
(.>=.) :: (Ord a, Applicative f) => f a -> f a -> f Bool
(.>=.) = liftA2 (>=)

infix 4 .>=
-- | The above type is a generalization for:
--
-- @
-- __(.>=)__ :: 'Ord' a => 'Clash.Signal.Signal' a -> a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('>=') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(.>=) :: (Ord a, Applicative f) => f a -> a -> f Bool
(.>=) a b = fmap (>=b) a

infix 4 >=.
-- | The above type is a generalization for:
--
-- @
-- __(>=.)__ :: 'Ord' a => a -> 'Clash.Signal.Signal' a -> 'Clash.Signal.Signal' 'Bool'
-- @
--
-- It is a version of ('>=') that allows comparing a @'Clash.Signal.Signal' a@ with a constant
-- @a@ and returns a 'Clash.Signal.Signal' of 'Bool'
(>=.) :: (Ord a, Applicative f) => a -> f a -> f Bool
(>=.) a b = fmap (a>=) b

instance Fractional a => Fractional (Signal dom a) where
(/) = liftA2 (/)
recip = fmap recip
Expand Down
2 changes: 1 addition & 1 deletion clash-prelude/tests/Clash/Tests/BlockRam.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ readRam
:: (HiddenClockResetEnable dom)
=> Signal dom (Unsigned 4)
-> Signal dom (Unsigned 8)
readRam addr = mux (register False $ addr .<. 8) ram (pure 0xff)
readRam addr = mux (register False $ addr .< 8) ram (pure 0xff)
where
ram = blockRam1 NoClearOnReset (SNat @8) 0 addr (pure Nothing)

Expand Down
2 changes: 1 addition & 1 deletion clash-prelude/tests/Clash/Tests/Ram.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ram rd we wr din =

maskOobRead :: Ram
maskOobRead rd we wr din =
maybeIsX <$> mux (rd .<. 2) ram0 (pure 4)
maybeIsX <$> mux (rd .< 2) ram0 (pure 4)
where
ram0 = asyncRam# clockGen clockGen enableGen d2 rd we wr din

Expand Down
2 changes: 1 addition & 1 deletion tests/shouldfail/Verification/NonTemporal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ assertCvResult
assertCvResult clk rst gen max results = done
where
counter = register clk rst gen (minBound :: n) (succ <$> counter)
done = hideAssertion results (counter .==. pure maxBound)
done = hideAssertion results (counter .== maxBound)
{-# INLINE assertCvResult #-}

binaryTest
Expand Down
2 changes: 1 addition & 1 deletion tests/shouldwork/Basic/AES.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ aes
-> Signal dom (BitVector 128)
-> Signal dom (BitVector 128)
-> Signal dom (Unsigned 4, Vec 4 (BitVector 32), BitVector 128, Bool)
aes start key block = bundle (cnt, roundKey, pack <$> roundState, cnt .==. 11)
aes start key block = bundle (cnt, roundKey, pack <$> roundState, cnt .== 11)
where

roundKey :: Signal dom (Vec 4 (BitVector 32))
Expand Down
4 changes: 2 additions & 2 deletions tests/shouldwork/Cores/Xilinx/DcFifo/Lfsr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ fifoVerifier ::
fifoVerifier clk rst ena actual = done0
where
expected = regEn clk rst ena 0 (isJust <$> actual) $ expected + 1
samplesDone = expected .>. 100
samplesDone = expected .> 100
stuckCnt :: Signal dom (Index 25000)
stuckCnt = regEn clk rst ena 0 (not <$> stuck) $ stuckCnt + 1
stuck = stuckCnt .==. pure maxBound
stuck = stuckCnt .== maxBound
-- Delay one cycle so assertion definitely triggers before stopping simulation
done = register clk rst ena False $ samplesDone .||. stuck
expected0 = liftA2 (<$) expected actual
Expand Down
10 changes: 2 additions & 8 deletions tests/shouldwork/Issues/T1187/Utils.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{-# LANGUAGE ScopedTypeVariables #-}
module T1187.Utils
( (.==)

, debounce
( debounce

, roundRobin

Expand All @@ -26,18 +24,14 @@ debounce _ initial this = regEn initial stable this
where
counter = register (0 :: Index (ClockDivider dom ps)) counter'
counter' = mux (unchanged initial this) counter 0
stable = counter' .==. pure maxBound
stable = counter' .== maxBound

roundRobin
:: forall n dom. (KnownNat n, HiddenClockResetEnable dom)
=> Signal dom Bool
-> (Signal dom (Vec n Bool), Signal dom (Index n))
roundRobin _next = undefined

infix 4 .==
(.==) :: (Eq a, Functor f) => f a -> a -> f Bool
fx .== y = (== y) <$> fx

moreIdx :: (Eq a, Enum a, Bounded a) => a -> a
moreIdx = fromMaybe maxBound . succIdx

Expand Down
4 changes: 2 additions & 2 deletions tests/shouldwork/Xilinx/ClockWizard.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ testBench ::
testBench = done
where
(o1, o2) = unbundle $ topEntity clkSE clkDiff rst
done1 = o1 .==. pure maxBound
done2 = o2 .==. pure maxBound
done1 = o1 .== maxBound
done2 = o2 .== maxBound
done = unsafeSynchronizer clockGen clkSE $ fmap endVhdlSim $
strictAnd <$> done1 <*> done2
strictAnd !a !b = a && b
Expand Down