by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
David Chambers
@davidchambers
What is the type of replaceIndex, @MikaAK?
Mika Kalathil
@MikaAK
@safareli correct, but how to apply fromMaybe(array.concat(replacement)) to replaceInArray
@davidchambers I'm actually not to great yet with signatures :( I have a hard time with creating them but I think it would be (a, b, c) -> a
David Chambers
@davidchambers
Let me see whether I understand the problem you're attempting to solve. Do you want to transform something like ['foo', 'bar', 'baz'] into ['foo', 'bar', 'quux'] by replacing the first occurrence of 'baz' with 'quux'?
Mika Kalathil
@MikaAK
basically, say I had ['foo', 'bar', 'baz'] I would like to use findAndReplace(R.equals('bar'), 'quux') to replace to ['foo', 'quux', 'baz'] or if the source array was ['foo', 'baz'] it would be ['foo', 'baz',' quux']
David Chambers
@davidchambers
I'm confused by the last bit. Do you want ['foo', 'baz'] to produce ['foo', 'baz', 'quux']?
Oh, I think I see what you're saying now. Replace the first occurrence if found, otherwise append to the input.
Mika Kalathil
@MikaAK
Exactly! Sorry if my wording was confusing, function should of been named addOrReplace
David Chambers
@davidchambers
I'm with you now. Give me a few minutes to play with it in the REPL. :)
Mika Kalathil
@MikaAK
Thanks :D
David Chambers
@davidchambers
@ram-bot
//    findIndex_ :: (a -> Boolean, Array a) -> Maybe Integer
const findIndex_ = (pred, xs) => {
  const idx = R.findIndex(pred, xs);
  return idx >= 0 ? S.Just(idx) : S.Nothing();
};

//    f :: (a -> Boolean, a, Array a) -> Array a
const f = (pred, repl, xs) =>
  S.maybe(R.append(repl, xs),
          S.compose(R.set(R.__, repl, xs), R.lensIndex),
          findIndex_(pred, xs));

[f(R.equals('baz'), 'quux', []),
 f(R.equals('baz'), 'quux', ['foo']),
 f(R.equals('baz'), 'quux', ['foo', 'bar']),
 f(R.equals('baz'), 'quux', ['foo', 'bar', 'baz'])];
ram-bot
@ram-bot
[ [ 'quux' ],
  [ 'foo', 'quux' ],
  [ 'foo', 'bar', 'quux' ],
  [ 'foo', 'bar', 'quux' ] ]
David Chambers
@davidchambers
This is idiomatic, I would say. The only problem is that R.append(repl, xs) happens regardless of whether the resulting value is needed. This inefficiency may or may not bother you. It's worth noting that this is not a problem in Haskell due to lazy evaluation.
Mika Kalathil
@MikaAK
That's actually kinda what I had but I have more steps in between maybe
But S.maybe is what I needed I think
Brad Compton (he/him)
@Bradcomp
Just a note that Ramda has R.update which can be used instead of a lens
R.update
David Chambers
@davidchambers
Good point, @Bradcomp. :)
Brad Compton (he/him)
@Bradcomp
@ram-bot
//    findIndex_ :: (a -> Boolean, Array a) -> Maybe Integer
const findIndex_ = (pred, xs) => {
  const idx = R.findIndex(pred, xs);
  return idx >= 0 ? S.Just(idx) : S.Nothing();
};

//    f :: (a -> Boolean, a, Array a) -> Array a
const f = (pred, repl, xs) =>
  S.maybe(R.append(repl, xs),
          R.update(R.__, repl, xs),
          findIndex_(pred, xs));

[f(R.equals('baz'), 'quux', []),
 f(R.equals('baz'), 'quux', ['foo']),
 f(R.equals('baz'), 'quux', ['foo', 'bar']),
 f(R.equals('baz'), 'quux', ['foo', 'bar', 'baz'])];
ram-bot
@ram-bot
[ [ 'quux' ],
  [ 'foo', 'quux' ],
  [ 'foo', 'bar', 'quux' ],
  [ 'foo', 'bar', 'quux' ] ]
Mika Kalathil
@MikaAK
Oooh perfect!
Well I'm hanging around here more for sure, I learned a bunch already thanks guys
David Chambers
@davidchambers
You're welcome. :)
Brad Compton (he/him)
@Bradcomp
:+1:
David Chambers
@davidchambers
@ram-bot
//    findIndex_ :: (a -> Boolean, Array a) -> Maybe Integer
const findIndex_ = (pred, xs) => {
  const idx = R.findIndex(pred, xs);
  return idx >= 0 ? S.Just(idx) : S.Nothing();
};

//    f :: (a -> Boolean, a, Array a) -> Array a
const f = (pred, repl, xs) => {
  const thunk =
  S.maybe(() => R.append(repl, xs),
          idx => () => R.update(idx, repl, xs),
          findIndex_(pred, xs));
  return thunk();
};

[f(R.equals('baz'), 'quux', []),
 f(R.equals('baz'), 'quux', ['foo']),
 f(R.equals('baz'), 'quux', ['foo', 'bar']),
 f(R.equals('baz'), 'quux', ['foo', 'bar', 'baz'])];
ram-bot
@ram-bot
[ [ 'quux' ],
  [ 'foo', 'quux' ],
  [ 'foo', 'bar', 'quux' ],
  [ 'foo', 'bar', 'quux' ] ]
Mika Kalathil
@MikaAK
:+1: on the lazy eval of append
David Chambers
@davidchambers
:)
The implementation is a bit less elegant, but this may be a price worth paying.
Julien Goux
@jgoux
Hi
Is there a global way of disabling sanctuary's typecheck without doing the const {create, env} = require('sanctuary') part ?
I can always import sanctuary and reexport it and then use my own "S" alias, but I'd prefer to use it without that
What is the point of having the typecheck with NODE_ENV=production ?
Most library disable warnings/check/errors on this flag (thinking about react)
Rick Medina
@rickmed
hey folks, anyone have references to good/balanced articles about the benefits/drawbacks of fp?
David Chambers
@davidchambers
I do not, @rickmed, but I would like to read some. :)
Irakli Safareli
@safareli
some time ago I was collecting good articles here but then I stoped and instead i'm just tweeting :p
David Chambers
@davidchambers
This question is well worth discussing, @jgoux. One thing to keep in mind is that type checking can be used to enforce invariants in one's programs which are particularly important in production. Type checking applications of withdraw :: PositiveFiniteNumber -> BankAccount -> BankAccount may not be important during development, but would be crucial in production to prevent negative withdrawals (i.e. deposits).
Rick Medina
@rickmed
yeah the thing is that is relatively easy to find fp introductory stuff or "OOP is bad! use fp instead!" but not that easy too find stuff like "hey, fp is awesome, but here is where is not that awesome..."
Rick Medina
@rickmed
hopefully "but here is where is not that awesome..." was not blasphemy in this channel :laughing:
David Chambers
@davidchambers
Not at all, @rickmed. ;)
If type checking is being used in this way, one would not want it to be disabled simply because NODE_ENV=production. Another situation in which tying checkTypes to NODE_ENV is problematic is property-based testing. These tests can be slow, so one may wish to disable type checking when running such tests locally. One would not want to set NODE_ENV=production, though, as this may have other effects such as having the test runner connect to a live database. The general problem is that having different behaviours depend on a single value means one can't adjust one setting independently of the others. A better solution would be to have a dedicated environment variable such as SANCTUARY_CHECK_TYPES. In fact, there's a module named plaid-sanctuary in Plaid's private npm registry which simply creates and exports a Sanctuary module with the value of checkTypes determined by this environment variable.
David Chambers
@davidchambers
In general, though, I don't think libraries should dictate a certain configuration mechanism. Environment variables aren't a good solution for front-end projects, and even for back-end projects some teams prefer config files. The easy option would be to ask users to mutate the module via S.checkTypes = false, but this would prevent type checking from being used in one module but not another, and would cause problems for projects which depend on Sanctuary both directly and indirectly.
The current approach is certainly cumbersome, but I believe it to be the best approach of the one's I've considered. The downsides of relying on NODE_ENV outweigh the benefits, but it's possible there's an equally convenient solution with less significant drawbacks.
Mika Kalathil
@MikaAK
if you happen to be using webpack you can alias you’re file to rexport S as sanctuary so it still reads as import * as S from ‘sanctuary’
David Chambers
@davidchambers
I have an apartment to call "home" for the first time in three months. I'm about to put my head down and spend the weekend tackling the tasks in #255. I'll start with Murmur and go from there. :headphones:
David Chambers
@davidchambers
The table of contents is now live at sanctuary.js.org. :smile:
Stefano Vozza
@svozza
Nice!
David Chambers
@davidchambers
Thanks for your feedback, @kedashoe.