These are chat archives for ramda/ramda

17th
Feb 2016
David Chambers
@davidchambers
Feb 17 2016 01:30 UTC
Arrows just clicked for me!
Scott Sauyet
@CrossEye
Feb 17 2016 01:31 UTC
Any easy-to-share insights from that?
David Chambers
@davidchambers
Feb 17 2016 01:32 UTC
Have you ever been writing a pipeline and realized you needed to use an anonymous function in order to reference its argument twice?
Sometimes it is possible to use R.converge/R.lift to avoid the lambda.
Scott Sauyet
@CrossEye
Feb 17 2016 01:32 UTC
all the time
David Chambers
@davidchambers
Feb 17 2016 01:33 UTC
But other times one wishes to apply several transformations to the argument without losing access to the original value.
Scott Sauyet
@CrossEye
Feb 17 2016 01:33 UTC
yes, arrows provide a context that makes this easy?
or at least straightforward?
I haven't really done any reading at all about arrows, just looking at that link now.
James Forbes
@JAForbes
Feb 17 2016 01:34 UTC
did ramda ever have an includes function? for strings?
David Chambers
@davidchambers
Feb 17 2016 01:35 UTC
We might have something like x => f(x, h(g(x))) somewhere in a pipeline and think it's a shame we can't include g and h in the pipeline (since we'd lose track of x).
But we could duplicate x, giving (x, x), then apply transformations to the second value in the tuple, giving (x, x'').
We could then, presumably, apply f to these two values.
This would give us one long, flat pipeline!
Scott Sauyet
@CrossEye
Feb 17 2016 01:37 UTC
@ram-bot R.contains('ab', 'flabby')
James Forbes
@JAForbes
Feb 17 2016 01:37 UTC
@davidchambers very interesting
Scott Sauyet
@CrossEye
Feb 17 2016 01:37 UTC
@JAForbes, bot not responding, but contains does work on Strings.
James Forbes
@JAForbes
Feb 17 2016 01:38 UTC
hmm I thought ramda kept strings and list separate, but I guess because the return type is a boolean its not really an issue whether to return a string/list
Scott Sauyet
@CrossEye
Feb 17 2016 01:39 UTC
I was just going to say that this sound very related to today's issue. I looked it up to find that @scott-christopher brought this up there. Is that what got you thinking?
James Forbes
@JAForbes
Feb 17 2016 01:39 UTC
Love the ram bot by the way, was that @raine's handy work?
David Chambers
@davidchambers
Feb 17 2016 01:39 UTC
Yep!
(To both questions, in fact.)
Scott Christopher
@scott-christopher
Feb 17 2016 01:44 UTC
@ram-bot R.contains('ab', 'flabby')
ram-bot
@ram-bot
Feb 17 2016 01:44 UTC
true
Scott Christopher
@scott-christopher
Feb 17 2016 01:44 UTC
I think it just needs backticks
Scott Sauyet
@CrossEye
Feb 17 2016 01:45 UTC
oh, ok
Scott Christopher
@scott-christopher
Feb 17 2016 01:49 UTC
@davidchambers The concepts of Arrows is effectively the same as Strong Profunctors too.
David Chambers
@davidchambers
Feb 17 2016 01:49 UTC
I haven't heard of such things. :)
Scott Christopher
@scott-christopher
Feb 17 2016 01:49 UTC
While ArrowChoice is represented by the Choice Profunctor
David Chambers
@davidchambers
Feb 17 2016 01:49 UTC
Step 1: Initial exposure.
Scott Christopher
@scott-christopher
Feb 17 2016 01:50 UTC
That's what makes up profunctor implementation of lenses/prisms
David Chambers
@davidchambers
Feb 17 2016 01:50 UTC
I love the way in which all these seemingly different ideas are related.
Scott Sauyet
@CrossEye
Feb 17 2016 01:51 UTC
I really only skimmed the profunctors stuff, but this is more straightforward for me to grasp, for whatever reason.
Scott Christopher
@scott-christopher
Feb 17 2016 01:51 UTC
It's all about riding those waves of "My gosh this is complicated" down to "Oh, it's actually pretty simple" and back again.
The diagrams on that Arrows page helps a lot
I started doing something similar for profunctors, but got distracted with actual work.
Scott Sauyet
@CrossEye
Feb 17 2016 01:52 UTC
doesn't that always get in the way?
David Chambers
@davidchambers
Feb 17 2016 01:52 UTC
I hate it when work gets in the way! ;)
Scott Sauyet
@CrossEye
Feb 17 2016 02:01 UTC
Just read both the article and Scott's comment, and I agree that we're onto something here. Damn, just when I wanted to get back to some documentation, too! :smile:
Scott Christopher
@scott-christopher
Feb 17 2016 02:17 UTC
@davidchambers If you think of a regular Arrow as using a Tuple to model parallel pipelines, ArrowChoice allows you to represent a choice of paths in your pipeline using Either. You can visualise this as a valve in your pipeline that switches path depending on whether the value is wrapped in a Left or Right.
David Chambers
@davidchambers
Feb 17 2016 02:18 UTC
That makes sense.
Scott Christopher
@scott-christopher
Feb 17 2016 02:34 UTC

So a prism can make use of this:

prism :: (a -> s) -> (s -> Either s a) -> Prism s a

Where the function given as the second argument is used to say whether a prism matched a given input or not, returning either a Left of the original input or a Right containing the focussed value.

The function given as the first argument is used to rebuild a focussed value back into the target type.
Richard Seldon
@arcseldon
Feb 17 2016 16:11 UTC
Just checking if people are familiar with this:
came across it today, and thought it might be worth sharing with the Ramda community.
Jim Argeropoulos
@ExploreMqt
Feb 17 2016 17:32 UTC
The has function in lodash lets you supply a string with period delimiters, allowing you to tunnel into a nested object. Ramda appears to only works on the outer most object. What would be the Ramda way to do _.has({foo: {bar: true}, 'foo.bar')?
David Chambers
@davidchambers
Feb 17 2016 17:33 UTC
Thank you, @scott-christopher! Prisms are beginning to make sense to me.
Raine Virta
@raine
Feb 17 2016 20:35 UTC
@ExploreMqt nothing immediately comes to mind
Jim Argeropoulos
@ExploreMqt
Feb 17 2016 20:41 UTC
If I were to work on a pull request for adding this ability, would it be accepted?
Raine Virta
@raine
Feb 17 2016 20:42 UTC
depends on how you'd do it
@ram-bot
const hasPath = curry((path, obj) =>
  pathSatisfies(has(last(path)), init(path), obj))

hasPath(['foo', 'bar', 'xyz'], { foo: { bar: { xyz: 1 } } })
ram-bot
@ram-bot
Feb 17 2016 20:43 UTC
true
Jim Argeropoulos
@ExploreMqt
Feb 17 2016 20:45 UTC
Thanks @ram-bot
Raine Virta
@raine
Feb 17 2016 20:48 UTC
ramda has taken the stance that it doesn't like stringified paths 'foo.bar.xyz'
Jim Argeropoulos
@ExploreMqt
Feb 17 2016 20:49 UTC
I'd be just fine with passing an array over a stringified path
Tom Duncalf
@tomduncalf
Feb 17 2016 21:27 UTC
hey there, i have a total beginners question :)
i am just trying to get my head around working with composition etc
what would be the canonical way to say "if true, return identity, otherwise return undefined"?
code example:
const cleanPostcode = R.compose(
  // what goes here to return R.identity (i.e. the postcode passed in to cleanPostcode) if R.test is true?
  R.test(POSTCODE_REGEX),
  R.toUpper,
  removeSpaces
)
is there anything more succinct than R.ifElse(R.test(POSTCODE_REGEX), R.identity, () => undefined),?
Raine Virta
@raine
Feb 17 2016 21:30 UTC
R.unless @tomduncalf
David Chambers
@davidchambers
Feb 17 2016 21:30 UTC

You could use

R.ifElse(R.test(POSTCODE_REGEX), R.identity, R.always(undefined))

though the idea of your function sometimes returning undefined is problematic.

Tom Duncalf
@tomduncalf
Feb 17 2016 21:30 UTC
ah yeah, well undefined is deliberate, kind of
as i am doing a basic FP presentation
and want to show where Maybe would come in useful :)
David Chambers
@davidchambers
Feb 17 2016 21:31 UTC
Ah, I see!
Good example, in that case. ;)
Raine Virta
@raine
Feb 17 2016 21:31 UTC
cool
Tom Duncalf
@tomduncalf
Feb 17 2016 21:31 UTC
how would I express that with R.unless?
R.always is good, didn't know that :)
Raine Virta
@raine
Feb 17 2016 21:32 UTC
but wouldn't your function explode in the R.toUpper step even if you add the ifElse there
Tom Duncalf
@tomduncalf
Feb 17 2016 21:33 UTC
no, as the input is always a string
so it goes string -> strip spaces -> to upper -> test against regex and return string if matches
kinda convoluted example really ;)
Raine Virta
@raine
Feb 17 2016 21:34 UTC
oh I read that as pipe, sorry
Tom Duncalf
@tomduncalf
Feb 17 2016 21:34 UTC
ah :)
is pipe more common than compose? i have been learning from the "DrBoolean" book which makes use of compose
but pipe does seem to make more sense from a programmer's POV
Michael Hurley
@buzzdecafe
Feb 17 2016 21:38 UTC
pipe is generally easier to read, since it reads in evaluation order. but i don't think it matters which one you choose
Raine Virta
@raine
Feb 17 2016 21:38 UTC
i'd imagine it's because drboolean seems to have quite strong haskell background where composition is just g . f
Tom Duncalf
@tomduncalf
Feb 17 2016 21:38 UTC
makes sense
in the book it says compose maps more closely to the mathematical definition of function composition
Michael Hurley
@buzzdecafe
Feb 17 2016 21:39 UTC
yes, usually defined as (f o g)(x) = f(g(x))
(didn't have time to lookup the ring symbol)
Tom Duncalf
@tomduncalf
Feb 17 2016 21:39 UTC
heh :)
basically i am presenting a high level overview of the boolean book to get people up to a basic level of understanding, as for me reading it made lots of stuff make sense that never did before...
so i think i will stick with compose for now
(as that is what is in the book)
and mention that pipe also exists
Michael Hurley
@buzzdecafe
Feb 17 2016 21:41 UTC
sounds completely reasonable
@CrossEye has a slide deck on functional js somewhere .....
Tom Duncalf
@tomduncalf
Feb 17 2016 21:43 UTC
oh that would be great to have a look at
Tom Duncalf
@tomduncalf
Feb 17 2016 21:44 UTC
awesome, I will take a look, thanks!
Tom Duncalf
@tomduncalf
Feb 17 2016 21:47 UTC
even better :+1:
Michael Hurley
@buzzdecafe
Feb 17 2016 21:48 UTC
2 yrs old, not sure what that means for ramda API in the examples. may have been a change or two since then
Tom Duncalf
@tomduncalf
Feb 17 2016 21:50 UTC
out of interest, what's the best way to search ramda by type signature?
i've just been copy/pasting the little arrow symbol and doing Find in my browser...