These are chat archives for ramda/ramda

3rd
Sep 2017
Joe Egan
@joeegan
Sep 03 2017 11:41
Greetings. Is there a way I can avoid all the map calls?
compose(
  map(zipObj(['base', 'counter'])),
  map(splitAt(3)),
  map(prop('name')),
)([{ name: 'USDGBP' }, { name: 'GBPEUR' }])

// => [{"base": "USD", "counter": "GBP"}, {"base": "GBP", "counter": "EUR"}]
Philipp Wille
@Yord
Sep 03 2017 11:44
@joeegan Jup! Be prepared for the awesomeness of point-free programming (and Ramda):
const res1 = compose(
  map(zipObj(['base', 'counter'])),
  map(splitAt(3)),
  map(prop('name')),
)([{ name: 'USDGBP' }, { name: 'GBPEUR' }])

const res2 = map(
  compose(
    zipObj(['base', 'counter']),
    splitAt(3),
    prop('name')
  )
)([{ name: 'USDGBP' }, { name: 'GBPEUR' }])

equals(res1, res2) // true
Joe Egan
@joeegan
Sep 03 2017 11:45
@Yord Nice!
@Yord Thanks
Philipp Wille
@Yord
Sep 03 2017 11:45
@joeegan Something very similar to this drove me into point-free. Isn't it just beautiful? :)
Joe Egan
@joeegan
Sep 03 2017 11:46
@Yord Truly
Philipp Wille
@Yord
Sep 03 2017 11:48
(should you enjoy theory: this is one of the functor laws:
compose(map(f), map(g)) == map(compose(f, g)))
Joe Egan
@joeegan
Sep 03 2017 11:53
@Yord I think I will now :smile:
Joe Egan
@joeegan
Sep 03 2017 12:20
I've just realised it'd actually be more useful if the return value was:
[{"base": "USD", "counter": "GBP", "id": "USDGBP"}, {"base": "GBP", "counter": "EUR", "id": "GBPEUR"}]
I'm assuming I'd need to change my approach fundamentally as I lose the name after the split.
Joe Egan
@joeegan
Sep 03 2017 13:06
Kinda got there with:
const instruments = [{ name: 'USDGBP' }, { name: 'GBPEUR' }]

const addBaseCounter =
  compose(
    zipObj(['base', 'counter']),
    splitAt(3),
    prop('name'),
  )

map(
  compose(
    omit('name'),
    inst => ({ ...inst, id: prop('name', inst)}),
    inst => merge(addBaseCounter(inst), inst)
  )
)(instruments)

// => [{"base": "USD", "counter": "GBP", id: "USDGBP"}, ...]
Joe Egan
@joeegan
Sep 03 2017 13:19
Searching for something more readable than:
instruments.map(({ name }) => {
  const [baseCurrency, counterCurrency] = splitAt(3, name);
  return {
    baseCurrency,
    counterCurrency,
    id: name,
  }
})
Kurt Milam
@kurtmilam
Sep 03 2017 17:54
@joeegan This point-free example seems to work correctly and may be possible to clean up a little:
const instruments = [ { name: 'USDGBP' }, { name: 'GBPEUR' } ]
const prepInstruments =
  pipe( prop( 'name' )
      , juxt( [ splitAt( 3 ), identity ] )
      , unnest
      , zipObj( [ 'baseCurrency', 'counterCurrency', 'id' ] )
      )
map( prepInstruments )
   ( instruments )
// -> [{"baseCurrency": "USD", "counterCurrency": "GBP", "id": "USDGBP"}, {"baseCurrency": "GBP", "counterCurrency": "EUR", "id": "GBPEUR"}]
Joe Egan
@joeegan
Sep 03 2017 17:58
@kurtmilam That looks great, I'll take a look into those methods, thanks
Kurt Milam
@kurtmilam
Sep 03 2017 17:59
:thumbsup: You're welcome!
EmilLindfors
@EmilLindfors
Sep 03 2017 18:23
Hey guys, is it possible to make a "long-click" (mousedown, mouseup) function in ramda? Specifically I'll be using it for counting so that the user can press a button and get an exponential increased R.add
Matthew Willhite
@miwillhite
Sep 03 2017 20:20
@EmilLindfors I think you’ll want to look at something like flyd or mostjs for time-specific functions