Skip to content

Commit

Permalink
Added condOf
Browse files Browse the repository at this point in the history
  • Loading branch information
polytypic committed Feb 12, 2018
1 parent b101c77 commit 9cc2995
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ parts. [Try Lenses!](https://calmm-js.github.io/partial.lenses/playground.html)
* [`L.choices(optic, ...optics) ~> optic`](#L-choices "L.choices: (POptic s a, ...POptic s a) -> POptic s a") <small><sup>v11.10.0</sup></small>
* [`L.choose((maybeValue, index) => optic) ~> optic`](#L-choose "L.choose: ((Maybe s, Index) -> POptic s a) -> POptic s a") <small><sup>v1.0.0</sup></small>
* [`L.cond(...[(maybeValue, index) => testable, consequentOptic][, [alternativeOptic]]) ~> optic`](#L-cond "L.cond: (...[(Maybe s, Index) -> Boolean, PLens s a][, [PLens s a]]) -> PLens s a") <small><sup>v13.1.0</sup></small>
* [`L.condOf(lens, ...[(maybeValue, index) => testable, consequentOptic][, [alternativeOptic]]) ~> optic`](#L-condOf "L.condOf: (PLens s c, ...[(Maybe c, Index) -> Boolean, PLens s a][, [PLens s a]]) -> PLens s a") <small><sup>v13.5.0</sup></small>
* [`L.ifElse((maybeValue, index) => testable, optic, optic) ~> optic`](#L-ifElse "L.ifElse: ((Maybe s, Index) -> Boolean) -> POptic s a -> POptic s a -> POptic s a") <small><sup>v13.1.0</sup></small>
* ~~[`L.iftes((maybeValue, index) => testable, consequentOptic, ...[, alternativeOptic]) ~> optic`](#L-iftes "L.iftes: ((Maybe s, Index) -> Boolean) -> PLens s a -> PLens s a -> PLens s a") <small><sup>v11.14.0</sup></small>~~
* [`L.orElse(backupOptic, primaryOptic) ~> optic`](#L-orElse "L.orElse: (POptic s a, POptic s a) -> POptic s a") <small><sup>v2.1.0</sup></small>
Expand Down Expand Up @@ -1255,8 +1256,8 @@ L.modify(majorAxis, R.negate, {x: -3, y: 1})
##### <a id="L-cond"></a> [](#contents) [](https://calmm-js.github.io/partial.lenses/index.html#L-cond) [`L.cond(...[(maybeValue, index) => testable, consequentOptic][, [alternativeOptic]]) ~> optic`](#L-cond "L.cond: (...[(Maybe s, Index) -> Boolean, PLens s a][, [PLens s a]]) -> PLens s a") <small><sup>v13.1.0</sup></small>

`L.cond` creates an optic whose operation is selected from the given optics and
predicates on the underlying view. See also [`L.choose`](#L-choose) and
[`L.ifElse`](#L-ifElse).
predicates on the underlying view. See also [`L.condOf`](#L-condOf),
[`L.choose`](#L-choose) and [`L.ifElse`](#L-ifElse).

```jsx
L.cond( [ predicate, consequent ]
Expand Down Expand Up @@ -1307,6 +1308,25 @@ vice versa. [`L.choose`](#L-choose) not only allows the optic to be chosen
dynamically, but also allows the optic to be constructed dynamically and using
the data at the focus.

##### <a id="L-condOf"></a> [](#contents) [](https://calmm-js.github.io/partial.lenses/index.html#L-condOf) [`L.condOf(lens, ...[(maybeValue, index) => testable, consequentOptic][, [alternativeOptic]]) ~> optic`](#L-condOf "L.condOf: (PLens s c, ...[(Maybe c, Index) -> Boolean, PLens s a][, [PLens s a]]) -> PLens s a") <small><sup>v13.5.0</sup></small>

`L.condOf` is like [`L.cond`](#L-cond), but the first argument to `L.condOf` is
a lens to get the parameters for the predicates from the underlying view.

For example:

```js
L.get(
L.condOf(
'type',
[R.equals('title'), 'text'],
[R.equals('text'), 'body']
),
{type: 'text', body: 'Try writing this with `L.cond`.'}
)
// 'Try writing this with `L.cond`.'
```

##### <a id="L-ifElse"></a> [](#contents) [](https://calmm-js.github.io/partial.lenses/index.html#L-ifElse) [`L.ifElse((maybeValue, index) => testable, optic, optic) ~> optic`](#L-ifElse "L.ifElse: ((Maybe s, Index) -> Boolean) -> POptic s a -> POptic s a -> POptic s a") <small><sup>v13.1.0</sup></small>

`L.ifElse` creates an optic whose operation is selected based on the given
Expand Down
25 changes: 25 additions & 0 deletions src/partial.lenses.js
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,10 @@ const seq2U = (l, r) => (x, i, M, xi2yM) =>

const pickInAux = (t, k) => [k, pickIn(t)]

//

const condOfCase = (p, o, r) => (y, j) => (p(y, j) ? o : r(y, j))

// Auxiliary

export const seemsArrayLike = x =>
Expand Down Expand Up @@ -812,6 +816,27 @@ export const cond = (process.env.NODE_ENV === 'production'
return r
})

export const condOf = (process.env.NODE_ENV === 'production'
? I.id
: fn => (of, ...cs) => {
const pair = C.tup(C.ef(reqFn), C.ef(reqOptic))
C.arr(pair)(cs.slice(0, -1))
C.arr(C.or(C.tup(C.ef(reqOptic)), pair))(cs.slice(-1))
return fn(of, ...cs)
})(function(of) {
of = toFunction(of)
let op = undefined
let n = arguments.length
while (--n) {
const c = arguments[n]
op =
c.length === 1
? I.always(toFunction(c[0]))
: condOfCase(c[0], toFunction(c[1]), op || I.always(zero))
}
return (x, i, C, xi2yC) => of(x, i, Const, op)(x, i, C, xi2yC)
})

export const ifElse = I.curry((c, t, e) =>
ifteU(c, toFunction(t), toFunction(e))
)
Expand Down
41 changes: 41 additions & 0 deletions test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ describe('arities', () => {
concat: 3,
concatAs: 4,
cond: 0,
condOf: 1,
count: 2,
countIf: 3,
counts: 2,
Expand Down Expand Up @@ -1422,6 +1423,46 @@ describe('L.cond', () => {
)
})

describe('L.condOf', () => {
testEq(
`L.collect(
[
L.elems,
L.condOf(
'type',
[R.equals('a'), 'foo'],
[R.equals('b'), 'bar'],
['lol']
)
],
[
{type: 'a', foo: 42},
{type: 'b', bar: 101},
{type: 'c', lol: 76}
]
)`,
[42, 101, 76]
)
testEq(
`L.collect(
[
L.elems,
L.condOf(
'type',
[R.equals('a'), 'foo'],
[R.equals('b'), 'bar']
)
],
[
{type: 'a', foo: 42},
{type: 'b', bar: 101},
{type: 'c', lol: 76}
]
)`,
[42, 101]
)
})

describe('L.ifElse', () => {
testEq(`L.set(L.ifElse(R.not, L.setOp(1), L.zero), 3, 2)`, 2)
testEq(`L.set(L.ifElse(R.not, L.setOp(1), L.zero), 3, 0)`, 1)
Expand Down
1 change: 1 addition & 0 deletions test/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const lazy = T.fn([T.fn([T_optic], T_optic)], T_optic)
export const choices = T.fnVarN(1, T_optic, T_optic)
export const choose = T.fn([T.fn([T_maybeDataO, T_index], T_optic)], T_optic)
export const cond = T.fnVarN(0, T.any, T_optic)
export const condOf = T.fnVarN(1, T.any, T_optic)
export const ifElse = T.fn(
[T.fn([T_maybeDataO, T_index], T.any), T_optic, T_optic],
T_optic
Expand Down

0 comments on commit 9cc2995

Please sign in to comment.