while trying to understand the usage of the function withClockResetEnable
in Clash.Prelude, I found the signature of this function like this:
withClockResetEnable
:: forall dom r. KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-> (HiddenClockResetEnable dom => r)
-> r
The thing really cause my confusion is this part
-> (HiddenClockResetEnable dom => r)
which has a comment below: The function with a hidden Clock, hidden Reset, and hidden Enable argument
My confusion is, my limited knowledge tell me, since there is a =>
, this line is maybe indicated a type constraint, like the polymorphic type r
should have an instance of HiddenClockResetEnable dom
, which still makes no sense to me, and I cannot link this line to the comment at all.
This is using the ImplicitParams
language option.
HiddenClockResetEnable
is defined as:
type HiddenClockResetEnable dom = (HiddenClock dom, HiddenReset dom, HiddenEnable dom)
Each of the parts such as HiddenClock
is defined like this:
type HiddenClock dom = (Hidden (HiddenClockName dom) (Clock dom), KnownDomain dom)
We have KnownDomain
in the constraints on withClockResetEnable
. So what is Hidden
?
type Hidden (x :: Symbol) a = IP x a
The IP
class is what the ImplicitParams
syntax desugars to. So the original signature means:
withClockResetEnable
:: forall dom r. KnownDomain dom
=> Clock dom
-> Reset dom
-> Enable dom
-> ((?clock :: Clock dom, ?reset :: Reset dom, ?enable :: Enable dom) => r)
-> r
In other words, if you call withClockResetEnable c r e f
, and f
is some computation that takes these parameters implicitly, then withClockResetEnable
will call f
with those arguments for the implicit parameters:
let
?clock = c
?reset = r
?enable = e
in f