简体   繁体   中英

Understanding Ramda.js

Question 1:

   var _curry1 = function _curry1(fn) {
        return function f1(a) {
            if (arguments.length === 0) {
                return f1;
            } else if (a != null && a['@@functional/placeholder'] === true) {
                return f1;
            } else {
                return fn.apply(this, arguments);
            }
        };
    };

What is the purpose of checking a['@@functional/placeholder'] === true ?

Question 2:

http://ramdajs.com/0.18.0/docs/#reduce

How do I read the notation?

(a,b -> a) -> a -> [b] -> a

This is my first time seeing such notation, where does it come from?

Question 1:

There is no "notation". __.js should clear it up:

module.exports = {'@@functional/placeholder': true};

so @@functional/placeholder is no different than foo in

a = { foo: true }
a.foo
a["foo"]

(Obviously, you can't write a.@@functional/placeholder because of all the odd symbols there.)

The intent is also seen in that file:

/**
 * A special placeholder value used to specify "gaps" within curried functions,
 * allowing partial application of any combination of arguments,
 * regardless of their positions.
 *
 * If `g` is a curried ternary function and `_` is `R.__`, the following are equivalent:
 *
 *   - `g(1, 2, 3)`
 *   - `g(_, 2, 3)(1)`
 *   - `g(_, _, 3)(1)(2)`
 *   - `g(_, _, 3)(1, 2)`
 *   - `g(_, 2, _)(1, 3)`
 *   - `g(_, 2)(1)(3)`
 *   - `g(_, 2)(1, 3)`
 *   - `g(_, 2)(_, 3)(1)`
 ...

So the intent is to be able to "skip" some places when currying. The test decides whether an argument is a real argument or the __.js placeholder, and behaves accordingly. Why it is @@functional/placeholder - presumably precisely because it is hoped that it is too weird, and will thus not collide with anyone's legitimate data.

Question 2:

The notation is standard in type theory, and popularised by Haskell. a and b are any types. (...) is a tuple of types, [a] is an list whose elements are a . a -> b is a function that takes an argument of type a and yields a return of type b , and is right-associative. The example in question reads:

It is a function that takes an argument a function that takes two arguments (of types a and b respectively) and returns a value of type a ; and yields a function that takes an argument of type a and returns a function that takes an argument that is a list of elements of type b , returning a value of type a .

This reads very confusingly, but an uncurried description will be a bit easier: it is a function that takes three arguments: the first one being a function (as described above), the second one being a value of a , the third one being a list of b elements, and returns a value of a .

Specifically, R.reduce is such a function: in

R.reduce(add, 10, numbers);

add is a function that takes two integers (both a and b being the same, integer), and returns an integer ( (a, b) -> a ); 10 is of type integer ( a ); numbers is a list of integers ( [b] ); and the return value is an integer ( a ).

Note that it mixes curried and uncurried syntax; if it was fully curried, add would be a -> b -> a , not (a, b) -> a .

Question 2:

That is a Hindley-Milner type signature. For the example given, 'a' and 'b' are arbitrary types and '->' is a function.

So lets break it down.

First, we take a type 'a' and a function 'b -> a'

(a, b -> a)

This returns a function, which returns a function,.. (cause you know, currying). The point is we can add '()' to make it a bit more readable.

(a, b -> a) -> (a -> ([b] -> a))

So if you pass this function 'a' and a function 'a' -> 'b', you get back

a -> ([b] -> a)

And if you pass this a type 'a'

[b] -> a

Where [b] is an array of type 'b's. Passing this function [b] gives you a type a

a

If you want to read more about functional programming in JavaScript, I can recommend The Mostly Adequate Guide

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM