While writing some code that uses clash-protocols, I implemented prod3C in the expected way:
prod3C
:: Circuit a b
-> Circuit c d
-> Circuit e f
-> Circuit (a, c, e) (b, d, f)
prod3C (Circuit x) (Circuit y) (Circuit z) =
Circuit
( \((xFwd, yFwd, zFwd), (xBwd, yBwd, zBwd)) ->
let
(xBwd', xFwd') = x (xFwd, xBwd)
(yBwd', yFwd') = y (yFwd, yBwd)
(zBwd', zFwd') = z (zFwd, zBwd)
in ((xBwd', yBwd', zBwd'), (xFwd', yFwd', zFwd'))
)
But this causes my hedgehog tests to hang. To fix this it was enough to make the pattern irrefutable by adding the tilde ~
:
:: Circuit a b
-> Circuit c d
-> Circuit e f
-> Circuit (a, c, e) (b, d, f)
prod3C (Circuit x) (Circuit y) (Circuit z) =
Circuit
( \ ~((xFwd, yFwd, zFwd), (xBwd, yBwd, zBwd)) ->
let
(xBwd', xFwd') = x (xFwd, xBwd)
(yBwd', yFwd') = y (yFwd, yBwd)
(zBwd', zFwd') = z (zFwd, zBwd)
in ((xBwd', yBwd', zBwd'), (xFwd', yFwd', zFwd'))
)
(I can’t post the rest of the code but plan to find a small reproducible example next week that I can post here).
Is there an obvious reason why I need the irrefutable pattern in prod3C while it’s not present in prod2C? Does it imply a problem elsewhere?