ramda functional-programming function-composition ramda.js

functional programming - ¿Cómo paso múltiples parámetros en una cadena de redacción de Ramda?



ramda npm (3)

Si tiene params y consultas como funciones al curry, puede:

EDIT: código con todas las campanas y silbatos necesarios para cambiar el orden de los parámetros o usar R.__ y stringify object

const endpoint = R.curry( str => `${str}` || ''default'' ) const protocol = R.curry( str => `https://${str}` ) const params = R.curry( (p, str) => `${str}?${p}` ) const query = R.curry( (q, str) => `${str}&query=${q}` ) let finalEndpoint = R.compose( query(JSON.stringify({ some:''value'', another:''value'' })), params(''sort=desc&part=true''), protocol, endpoint ) var result = finalEndpoint(''api.content.io'') console.log(result)

Aquí hay cuatro funciones que intento componer en una única cadena de punto final:

const endpoint = str => `${str}` || ''default'' const protocol = str => `https://${str}` const params = str => `${str}?sort=desc&part=true&` const query = str => `${str}query={ some:''value'', another:''value''}` let finalEndpoint = R.compose(query, params, protocol, endpoint) var result = finalEndpoint(''api.content.io'')

Esta composición funciona y devuelve el resultado que quiero, que es:

https://api.content.io?sort=desc&part=true&query={ some:''value'', another:''value''}

Pero observe cómo he codificado los valores para params y query dentro de su cuerpo de función. Solo veo un valor que sube el valor en esta cadena R.compose .

¿Cómo y dónde exactamente paso los parámetros y parámetros de consulta?

ACTUALIZAR:

Lo que hice fue curry esas funciones como esta:

var R = require(''ramda''); const endpoint = str => `${str}` || ''default'' const protocol = str => `https://${str}` const setParams = R.curry ( (str, params) => `${str}?${params}` ) const setQuery = R.curry ( (str, query) => `${str}&query=${JSON.stringify(query)}` )

y entonces

let finalEndpoint = R.compose(protocol, endpoint) var result = setQuery(setParams(finalEndpoint(''api.content.io''), ''sort=desc&part=true''), { some:''value'', another:''value''}) console.log(result);

Pero la última llamada para obtener un result parece bastante hackeada y poco elegante. ¿Hay alguna forma de mejorar esto?


¿Cómo y dónde exactamente paso los parámetros y parámetros de consulta?

Honestamente, no lo hace, no cuando está compilando un pipe compose o pipe con Ramda o bibliotecas similares.

Ramda (descargo de responsabilidad: soy uno de los autores) permite que la primera función reciba múltiples argumentos, algunas otras bibliotecas, otras no, pero las siguientes solo recibirán el resultado de las llamadas anteriores. Hay una función en Sanctuary , meld , que podría ser útil con esto, pero tiene una API bastante compleja.

Sin embargo, realmente no entiendo por qué estás construyendo esta función de esta manera en primer lugar. ¿Son esas funciones intermedias realmente reutilizables, o las estás construyendo según las especificaciones? La razón por la que pregunto es que esta parece ser una versión más sensata de la misma idea:

const finalEndpoint = useWith( (endpoint, params, query) =>`https://${endpoint}?${params}&query=${query}`, [ endpoint => endpoint || ''default'', pipe(toPairs, map(join(''='')), join(''&'')), pipe(JSON.stringify, encodeURIComponent) ] ); finalEndpoint( ''api.content.io'', {sort: ''desc'', part: true}, {some:''value'', another:''value''} ); //=> "https://api.content.io?sort=desc&part=true&query=%7B%22some%22%3A%22value%22%2C%22another%22%3A%22value%22%7D"

Realmente no conozco tus requisitos para ese último parámetro. Me pareció extraño sin ese encodeUriComponent , pero tal vez no lo necesites. Y también tomé libertades con el segundo parámetro, suponiendo que preferiría datos reales en la API a una cadena que encapsulara esos datos. Pero si quiere pasar ''sort=desc&part=true'' , entonces reemplace pipe(toPairs, map(join(''='')), join(''&'')) con identity .

Como todo está lejos de estar libre de puntos, no usé una versión sin puntos de la primera función, tal vez or(__, ''default'') , ya que creo que lo que hay allí es más legible.

Actualizar

Puede ver una versión de esto en Ramda REPL , una que agrega algunas instrucciones console.log con tap .

Esto plantea una pregunta interesante para Ramda. Si esas funciones intermedias son realmente deseables, Ramda no ofrece ninguna forma de combinarlas. Obviamente, Ramda podría ofrecer algo como meld , pero ¿hay un término medio? Me pregunto si hay una función útil (al curry, por supuesto) que debemos incluir que funciona algo así como

someFunc([f0], [a0]); //=> f0(a0) someFunc([f0, f1], [a0, a1]); //=> f1(f0(a0), a1) someFunc([f0, f1, f2], [a0, a1, a2]); //=> f2(f1(f0(a0), a1), a2) someFunc([f0, f1, f2, f3], [a0, a1, a2, a3]); //=> f3(f2(f1(f0(a0), a1), a2), a3) // ...

Hay algunas objeciones serias: ¿Qué pasa si las listas son de diferentes longitudes? ¿Por qué la llamada inicial es unitaria y deberíamos solucionarlo agregando un parámetro de acumulador separado a la función? No obstante, esta es una función intrigante, y probablemente la plantearé para su discusión en los tableros de Ramda.


Escribí una pequeña función auxiliar para situaciones como esta.

Es como componer, pero con los parámetros de descanso también pasaron. El primer parámetro es el valor de retorno de la función anterior. Los parámetros restantes no cambian.

Con él, puedes reescribir tu código de la siguiente manera:

const compound = require(''compound-util'') const endpoint = str => `${str}` || ''default'' const protocol = str => `https://${str}` const params = (str, { params }) => `${str}?${params}` const query = (str, { query }) => `${str}query=${query}` const finalEndpoint = compound(query, params, protocol, endpoint) const result = finalEndpoint(''api.content.io'', { params: ''sort=desc&part=true&'', query: JSON.stringify({ some:''value'', another:''value''}) })