ramda-adjunct
ramda-adjunct copied to clipboard
lensSlice
Is your feature request related to a problem? Please describe. Python-style pure slice and set slice encapsulated in a lens.
Describe the solution you'd like
const lensSlice = (bgn, end) => R.lens(
R.slice(bgn, end),
(value, target) => R.useWith(
R.apply(RA.concatAll),
[RA.sliceTo(bgn), R.identity, RA.sliceFrom(end)]
)(oldVal, newVal, oldVal)
Describe alternatives you've considered
--
Additional context
Original comment of the issue author: Python-style pure slice and set slice encapsulated in a lens:
const lensSlice = (bgn, end) => R.lens(
R.slice(bgn, end),
(newVal, oldVal) => oldVal.slice(0, bgn).concat(newVal).concat(oldVal.slice(end)))
Probably it could be rewritten to be more readable, but it's just proof-of-concept.
Example:
const lens = lensSlice(0, 2)
R.set(lens, '1212', 'aasdf') //=> "1212sdf"
Python for comparison (used list because strings are immutable, and set slice is mutating IIRC):
>>> a = list('aasdf')
>>> a[0:2] = '1212'
>>> a
['1', '2', '1', '2', 's', 'd', 'f']
R.set(lens, Array.from('1212'), Array.from('aasdf')) //=> ["1", "2", "1", "2", "s", "d", "f"]
Related: https://github.com/calmm-js/partial.lenses#L-prefix https://github.com/calmm-js/partial.lenses#L-slice
Legitimate; but I would simplify the composition and use already established tools for that
const lensSlice = (bgn, end) => R.lens(
R.slice(bgn, end),
(value, target) => R.useWith(
R.apply(RA.concatAll),
[RA.sliceTo(bgn), R.identity, RA.sliceFrom(end)]
)(oldVal, newVal, oldVal)
Ref https://www.linkedin.com/pulse/functional-lenses-javascript-vladim%C3%ADr-gorej/ for naming Ref concatAll need to implemented first to allow this composition
We could also define setSlice
:
const setSlice = R.curry((bgn, end, replacement, target) =>
RA.concatAll([RA.sliceTo(bgn, target), replacement, RA.sliceFrom(end, target)]))
// Then
const lensSlice = R.curry((bgn, end) => R.lens(R.slice(bgn, end), setSlice(bgn, end)))
// const lensSlice = R.converge(R.lens, [R.slice, setSlice]) // doesn't work
And perhaps using fromIndex
instead of bgn
and toIndex
instead of end
would be a good idea (R.slice
uses those names).
I'd tackle this after concatAll
.
Create a separate issue for setSlice
. See the R.adjunct before doing so. I'd go for a name adjustSlice
instead of setSlice
.
I don't think opening an issue is necessary, I don't think it needs discussion. Except name, for which I suggest updateSlice
, because it's more akin to R.update
than R.adjust
.
@GingerPlusPlus We create a separate issue for each function (except where two are basically inversions of each other), so please open a new issue for RA.updateSlice
so it can be discussed separately.