Open kleinreact opened 1 month ago
Right, currently, | Function | Argument 1 | Argument 2 |
---|---|---|---|
shiftInAt0 |
lazy | strict | |
shiftInAtN |
strict | lazy |
Which is why:
rotateRightS' :: forall d n a. KnownNat n => Vec n a -> SNat d -> Vec n a
rotateRightS' input SNat = output
where
(output, feedback) = shiftInAt0 @n @_ @d input feedback
diverges, as it uses its recursive result in the strict argument position. To make it not diverge you have to do:
rotateRightS' :: forall d n a. KnownNat n => Vec n a -> SNat d -> Vec n a
rotateRightS' input SNat = output
where
(output, feedback) = shiftInAt0 @n @_ @d input (lazyV feedback)
The reason for all of this is my/our desire to built functions within the Vector
module out of existing functions in the Vector
module; as opposed to adding a new recursive function. Though this is mostly coming from a position where:
We can make the type arguments have the same order, so n m a
. But otherwise I wouldn't want to make any changes in order to achieve symmetry. I would probably update the documentation to highlight the strictness of the arguments. I could be convinced otherwise though.
I'm fine with keeping the operations asymmetric with respect to their argument strictness, as long as this is clear to the user. It's just something that might be overseen easily otherwise.
We can make the type arguments have the same order, so n m a. But otherwise I wouldn't want to make any changes in order to achieve symmetry. I would probably update the documentation to highlight the strictness of the arguments.
:+1:
I noticed some unexpected differences between
shiftInAt0
andshiftInAtN
:shiftInAt0
requiresKnownNat n
, whileshiftInAtN
requiresKnownNat m
.shiftInAt0
is implicitly quantified viaforall n a m
, whileshiftInAtN
is implicitly quantified viaforall m n a
.rotateLeftS
androtateRightS
viashiftInAt0
andshiftInAtN
utilizing their duality (see some example code below), thenrotateLeftS'
definition returns on some input in the REPL, whilerotateRightS'
does not.We either should give both operations some symmetric behavior or we should explain, why we like them to be different on purpose.