@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.
```

@davidchambers my head just exploded

@davidchambers i wasn't aware the sanctuary error messages are awesome like that

:+1:

@davidchambers wasn't either better because if R.isNil, R.isEmpty never get to run. I don't follow the error

@davidchambers R.isNIl return either true or false so how is it not satisfying the type-class constraint

@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. :)
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`

.
@ram-bot

`R.or`

`[Function: f2]`

- →
*→*

R.or

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?

How do I use pipe to call

Any Ideas?

Example:

`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)) //...
```

`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');//->"å∫ç"
```

cool @dtipson

@easyrider What are you trying to do?

@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

@easyrider would the type signature look like

`[[a]] -> [[a]]`

?
@easyrider http://goo.gl/2vGts6 like this?

@Bradcomp - wow great - that's what i wanted - Thank you for your help

:+1:

Hey guys! Quick question, when I say

`foo :: a -> b`

, can `b`

be still of the same type as `a`

?
yes

Yes! it can be, but it doesn't have to be!

but

`foo :: a -> a`

means it would return the same type, correct?
Correct

Awesomeburgersauce

thanks :D

Type Signatures [√]

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.
yes

but now I know that e.g.

`foo :: List a -> List b`

would return a list of a different type (maybe)
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`

- Everything on the left of
`=>`

within the type signature, is there to describe a type alias? - 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`

?
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

@GrosSacASac uhm... just use keyDown I guess?

@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.
right?

The point of that section is about aliasing, so

`User Name`

should be considered the same as `User String`

and `Url`

as a `String`

.
imo shouldn't this be

`// toUrl :: Url -> User -> Url`

?
since you pass the user Object?

It suggests that

`User`

is parameterised, so it is expecting another type to indicate the some extra detail about the `User`

.
Ah I see

Like a

`List Int`

is a list of integers, or a `Maybe String`

is potentially a string.
mind explaining

here, we describe

`// 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?
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`

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.
mhmm

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]`

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

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.
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?

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`

.
yes,

`s`

is just some generic type, right?
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`

ahhh

:thumbsup:

thanks a bunch

no problem :)