These are chat archives for ramda/ramda

17th
Feb 2016
David Chambers
@davidchambers
Feb 17 2016 01:30
Arrows just clicked for me!
Scott Sauyet
@CrossEye
Feb 17 2016 01:31
Any easy-to-share insights from that?
David Chambers
@davidchambers
Feb 17 2016 01:32
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
all the time
David Chambers
@davidchambers
Feb 17 2016 01:33
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
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
did ramda ever have an includes function? for strings?
David Chambers
@davidchambers
Feb 17 2016 01:35
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
@ram-bot R.contains('ab', 'flabby')
James Forbes
@JAForbes
Feb 17 2016 01:37
@davidchambers very interesting
Scott Sauyet
@CrossEye
Feb 17 2016 01:37
@JAForbes, bot not responding, but contains does work on Strings.
James Forbes
@JAForbes
Feb 17 2016 01:38
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
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
Love the ram bot by the way, was that @raine's handy work?
David Chambers
@davidchambers
Feb 17 2016 01:39
Yep!
(To both questions, in fact.)
Scott Christopher
@scott-christopher
Feb 17 2016 01:44
@ram-bot R.contains('ab', 'flabby')
ram-bot
@ram-bot
Feb 17 2016 01:44
true
Scott Christopher
@scott-christopher
Feb 17 2016 01:44
I think it just needs backticks
Scott Sauyet
@CrossEye
Feb 17 2016 01:45
oh, ok
Scott Christopher
@scott-christopher
Feb 17 2016 01:49
@davidchambers The concepts of Arrows is effectively the same as Strong Profunctors too.
David Chambers
@davidchambers
Feb 17 2016 01:49
I haven't heard of such things. :)
Scott Christopher
@scott-christopher
Feb 17 2016 01:49
While ArrowChoice is represented by the Choice Profunctor
David Chambers
@davidchambers
Feb 17 2016 01:49
Step 1: Initial exposure.
Scott Christopher
@scott-christopher
Feb 17 2016 01:50
That's what makes up profunctor implementation of lenses/prisms
David Chambers
@davidchambers
Feb 17 2016 01:50
I love the way in which all these seemingly different ideas are related.
Scott Sauyet
@CrossEye
Feb 17 2016 01:51
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
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
doesn't that always get in the way?
David Chambers
@davidchambers
Feb 17 2016 01:52
I hate it when work gets in the way! ;)
Scott Sauyet
@CrossEye
Feb 17 2016 02:01
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
@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
That makes sense.
Scott Christopher
@scott-christopher
Feb 17 2016 02:34

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
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
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
Thank you, @scott-christopher! Prisms are beginning to make sense to me.
Raine Virta
@raine
Feb 17 2016 20:35
@ExploreMqt nothing immediately comes to mind
Jim Argeropoulos
@ExploreMqt
Feb 17 2016 20:41
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
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
true
Jim Argeropoulos
@ExploreMqt
Feb 17 2016 20:45
Thanks @ram-bot
Raine Virta
@raine
Feb 17 2016 20:48
ramda has taken the stance that it doesn't like stringified paths 'foo.bar.xyz'
Jim Argeropoulos
@ExploreMqt
Feb 17 2016 20:49
I'd be just fine with passing an array over a stringified path
Tom Duncalf
@tomduncalf
Feb 17 2016 21:27
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
R.unless @tomduncalf
David Chambers
@davidchambers
Feb 17 2016 21:30

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
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
Ah, I see!
Good example, in that case. ;)
Raine Virta
@raine
Feb 17 2016 21:31
cool
Tom Duncalf
@tomduncalf
Feb 17 2016 21:31
how would I express that with R.unless?
R.always is good, didn't know that :)
Raine Virta
@raine
Feb 17 2016 21:32
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
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
oh I read that as pipe, sorry
Tom Duncalf
@tomduncalf
Feb 17 2016 21:34
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
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
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
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
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
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
sounds completely reasonable
@CrossEye has a slide deck on functional js somewhere .....
Tom Duncalf
@tomduncalf
Feb 17 2016 21:43
oh that would be great to have a look at
Tom Duncalf
@tomduncalf
Feb 17 2016 21:44
awesome, I will take a look, thanks!
Tom Duncalf
@tomduncalf
Feb 17 2016 21:47
even better :+1:
Michael Hurley
@buzzdecafe
Feb 17 2016 21:48
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
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...