These are chat archives for ramda/ramda

13th
Apr 2016
David Chambers
@davidchambers
Apr 13 2016 06:26
@6ewis, it's worth noting that had you been using S.or rather than R.or earlier, the type error would have been apparent:
S.or(R.isNil, R.isEmpty);
// ! TypeError: Type-class constraint violation
//
//   or :: Alternative a => a -> a -> a
//         ^^^^^^^^^^^^^    ^
//                          1
//
//   1)  function f1(a) {
//               if (arguments.length === 0 || _isPlaceholder(a)) {
//                   return f1;
//               } else {
//                   return fn.apply(this, arguments);
//               }
//           } :: Function, TypeRep
//
//   ‘or’ requires ‘a’ to satisfy the Alternative type-class constraint; the value at position 1 does not.
Tobias Pflug
@gilligan
Apr 13 2016 07:44
@davidchambers my head just exploded
@davidchambers i wasn't aware the sanctuary error messages are awesome like that
:+1:
Lewis
@6ewis
Apr 13 2016 12:31
@davidchambers wasn't either better because if R.isNil, R.isEmpty never get to run. I don't follow the error
Lewis
@6ewis
Apr 13 2016 15:13
@davidchambers R.isNIl return either true or false so how is it not satisfying the type-class constraint
Aldwin Vlasblom
@Avaq
Apr 13 2016 15:17

@6ewis Both R.or and S.or expect you to give it two Alternatives (Boolean-like values). Sanctuary is the only one that performs type-checking on the input, though.

Maybe the difference between R.or and R.either is best shown by naively implementing the two:

R.or = function(a, b){ return a || b }
R.either = function(f, g, x){ return f(x) || g(x) }

So when you pass two functions into R.or, like you tried, you're just going to the the first one back, which is what I showed: R.or(R.isNil, R.isEmpty) === R.isNil.

...which meant that your function: compose(or(isNil, isEmpty), trim), was the same as compose(isNil, trim), which returned false for empty values, of course. :)
Aldwin Vlasblom
@Avaq
Apr 13 2016 15:28
What David demonstrated is that were you to have used S.or, it would've immediately been brought to your attention that you're passing a weird type into or, namely a Function, TypeRep, which is not an Alternative.
Lewis
@6ewis
Apr 13 2016 15:51
@ram-bot
R.or
ram-bot
@ram-bot
Apr 13 2016 15:51
[Function: f2]
Lewis
@6ewis
Apr 13 2016 15:51
R.or
Lewis
@6ewis
Apr 13 2016 15:52
Here you go. I thought I could pass a function as long as it returns a boolean
@Avaq And I actually interpreted the fact that it wasn't working differently; my thinking was that R.isNil returned false so R.isEmpty never ran
@Avaq thanks for the info; is it best practice to use S for better debugging?
Adam
@easyrider
Apr 13 2016 16:55
How do I use pipe to call R.take every time with decreased value - that is 1st call take(5), 2nd call take(4) etc.
Any Ideas?
Example:
R.pipe( R.map(R.take(5)) //...
Drew
@dtipson
Apr 13 2016 17:20
flip(props) is a pretty cool way to translate arrays/strings using a map/dict:
const mapTo = flip(props);  
const weirdDict = compose( join(''), mapTo({a:'å',b:'∫',c:'ç'}));
weirdDict('abc');//->"å∫ç"
Jose Luis
@josete89
Apr 13 2016 17:21
cool @dtipson
Brad Compton (he/him)
@Bradcomp
Apr 13 2016 18:28
@easyrider What are you trying to do?
Adam
@easyrider
Apr 13 2016 20:34
@Bradcomp For example: if I have 3 arrays I want to get 5 elements from first, 4 from 2nd, 3 from 3rd etc - I am curious if it's possible to do in a point free style using pipe/compose - that's why I ask
Brad Compton (he/him)
@Bradcomp
Apr 13 2016 20:35
@easyrider would the type signature look like [[a]] -> [[a]]?
Brad Compton (he/him)
@Bradcomp
Apr 13 2016 20:41
@easyrider http://goo.gl/2vGts6 like this?
Adam
@easyrider
Apr 13 2016 20:44
@Bradcomp - wow great - that's what i wanted - Thank you for your help
Brad Compton (he/him)
@Bradcomp
Apr 13 2016 20:44
:+1:
Martin Broder
@mrtnbroder
Apr 13 2016 21:15
Hey guys! Quick question, when I say foo :: a -> b, can b be still of the same type as a?
Chet Harrison
@ChetHarrison
Apr 13 2016 21:15
yes
Brad Compton (he/him)
@Bradcomp
Apr 13 2016 21:15
Yes! it can be, but it doesn't have to be!
Martin Broder
@mrtnbroder
Apr 13 2016 21:16
but foo :: a -> a means it would return the same type, correct?
Brad Compton (he/him)
@Bradcomp
Apr 13 2016 21:16
Correct
Martin Broder
@mrtnbroder
Apr 13 2016 21:16
Awesomeburgersauce
thanks :D
Type Signatures [√]
Brad Compton (he/him)
@Bradcomp
Apr 13 2016 21:19
It should be mentioned that a in this case should be valid for any type a, in the absence of further type constraints
So in this case, foo :: a -> a can really only be the identity function.
Martin Broder
@mrtnbroder
Apr 13 2016 21:26
yes
but now I know that e.g. foo :: List a -> List b would return a list of a different type (maybe)
Martin Broder
@mrtnbroder
Apr 13 2016 22:02
I'm not sure I completly understand this: https://github.com/ramda/ramda/wiki/Type-Signatures#type-aliases
// toUrl :: User Name u => Url -> u -> Url
  1. Everything on the left of => within the type signature, is there to describe a type alias?
  2. Why does it say User Name u when u is actually of type User? I guess I read it wrong?
I mean, do I read it like this: User, Name, u (split values) or as one User Name u?
Walle Cyril
@GrosSacASac
Apr 13 2016 22:09
I don't know what event property I should use to know if the user pressed "g", "r" or " s" https://developer.mozilla.org/en-US/docs/Web/Events/keydown
Martin Broder
@mrtnbroder
Apr 13 2016 22:11
@GrosSacASac uhm... just use keyDown I guess?
Scott Christopher
@scott-christopher
Apr 13 2016 22:15
@mrtnbroder That type doesn't look correct to me. Based on the description I would have expected it to be toUrl :: Url -> User Name -> Url instead.
Martin Broder
@mrtnbroder
Apr 13 2016 22:16
right?
Scott Christopher
@scott-christopher
Apr 13 2016 22:16
The point of that section is about aliasing, so User Name should be considered the same as User String and Url as a String.
Martin Broder
@mrtnbroder
Apr 13 2016 22:17
imo shouldn't this be // toUrl :: Url -> User -> Url?
since you pass the user Object?
Scott Christopher
@scott-christopher
Apr 13 2016 22:18
It suggests that User is parameterised, so it is expecting another type to indicate the some extra detail about the User.
Martin Broder
@mrtnbroder
Apr 13 2016 22:18
Ah I see
Scott Christopher
@scott-christopher
Apr 13 2016 22:18
Like a List Int is a list of integers, or a Maybe String is potentially a string.
Martin Broder
@mrtnbroder
Apr 13 2016 22:20
mind explaining // Lens s a = Functor f => (a -> f a) -> s -> f s to me though @scott-christopher ?
here, we describe s and a of type Lens and f of type Functor, correct?
Scott Christopher
@scott-christopher
Apr 13 2016 22:22
So Lens s a is acting as an alias here for the more complex type to the right of the =
So you can read that as, when ever you see a type signature refer to a Lens s a, it actually wants a (a -> f a) -> s -> f s where f is some Functor
So if we hypothetically had a Lens Object Int (a lens takes an object and focusses on an integer inside it), that translates to the actual type of (Int -> f Int) -> Object -> f Object
Scott Christopher
@scott-christopher
Apr 13 2016 22:27
the Functor f part indicates that any type can be used for f in the signature to the right of the =>, as long as it implements the Functor spec.
Martin Broder
@mrtnbroder
Apr 13 2016 22:31
mhmm
Scott Christopher
@scott-christopher
Apr 13 2016 22:32
Without getting too bogged down into the implementation of lenses, we can have a look at https://github.com/ramda/ramda/blob/v0.21.0/src/over.js#L37 and see that lens which has type Lens s a, takes function(y) { return Identity(f(y)); } as its first argument. This corresponds to the (a -> f a) in Functor f => (a -> f a) -> s -> f s, where f is the Identity functor in this case.
Lenses can be a little mind boggling though, so perhaps a better example to use is map :: Functor f => (a → b) → f a → f b
map takes a function that accepts some type a and returns some type b, along with some type f a that is a Functor that holds something of type a.
The list type implements functor, so when just talking about lists, we could change the type signature of map to (a -> b) -> [a] -> [b]
Martin Broder
@mrtnbroder
Apr 13 2016 22:37
It slowly starts to make sense
Ahh I got the Functor part.
thanks a lot that really helped me
reading it again and again :D
Scott Christopher
@scott-christopher
Apr 13 2016 22:46
If you've done any work with typed object oriented languages, you can kinda think of the type constraints like Functor f as saying the f used in the type signature must implement the Functor interface.
Martin Broder
@mrtnbroder
Apr 13 2016 22:53
to give an example
// lens :: Lens Object Int
const lens = R.lensProp('x')
this would say lens expecting an Object that focuses on a property that is of type Int
is that right?
Scott Christopher
@scott-christopher
Apr 13 2016 22:57
Yeah, though just to clarify, it is not a function that takes an Object as its argument, it is just describing a Lens that knows how to zoom into an Object.
Martin Broder
@mrtnbroder
Apr 13 2016 22:59
yes, s is just some generic type, right?
Scott Christopher
@scott-christopher
Apr 13 2016 23:00
Right. We use the type alias of Lens Object Int here because it easier to describe the intent rather than Functor f => (Int -> f Int) -> Object -> f Object
Martin Broder
@mrtnbroder
Apr 13 2016 23:02
ahhh
Scott Christopher
@scott-christopher
Apr 13 2016 23:03
:thumbsup:
Martin Broder
@mrtnbroder
Apr 13 2016 23:03
thanks a bunch
Scott Christopher
@scott-christopher
Apr 13 2016 23:04
no problem :)