Tengo dos funciones al curry f
y g
:
f: a -> b -> c g: a -> c -> d
Quiero crear h
:
h: a -> b -> d
Actualmente los estoy componiendo a través pipe
:
const h = a => pipe(f(a), g(a));
¿Hay alguna manera de hacer este punto gratis?
La razón por la que pregunto es porque quiero que el código sea lo más legible posible. En algunos de mis casos, hay más de dos funciones que reciben argumentos iniciales en la composición y estoy tratando de evitar pasar argumentos repetidamente.
Intenté algo como:
const h = converge(pipe, [f, g]);
que por alguna razón no funciona. Supongo que no entiendo converge
correctamente.
Editar:
Intenté lo que sugirió Ori Drori, pero no funciona.
const modulo = divisor => dividend => dividend % divisor; const maybeReduceByModulo = modulo => number => number >= 0 ? number : number + modulo; export const maybeReducedModulo = flip(ap)(modulo, maybeReduceByModulo); /** * Before: * export const maybeReducedModulo = divisor => * pipe(modulo(divisor), maybeReduceByModulo(divisor)); */
Ramda (descargo de responsabilidad: soy un autor de Ramda) no puede ofrecer directamente todos los combinadores que uno pueda necesitar. Contiene varios de ellos. Pero para aquellos que no contiene, a menudo es trivial escribir su propia versión. Para mí el gran problema está en nombrar. Es difícil encontrar nombres para ellos, e incluso aquellos que recurren a nombres de pájaros solo pueden dar nombres para algunos de la infinidad de posibilidades.
No puedo encontrar este en la práctica lista de combinadores de Avaq, ni puedo encontrar :: (a -> b -> c) -> (a -> c -> d) -> a -> b -> d
o :: (a -> b -> c) -> (a -> c -> d) -> (a -> b -> d)
en Hoogle , lo que me hace sospechar que este es un requisito bastante poco común. Pero si es un requisito que tienes, inventa tu propio nombre.
Una vez que haya elegido un nombre, estos combinadores a menudo se escriben solos.
const foo = (f) => (g) => (x) => (y) => g (x) (f (x) (y)) const f = (a) => (b) => `f (${a}, ${b})` const g = (a) => (c) => `g (${a}, ${c})` const h = foo (f) (g) console .log (h ('a') ('b'))
Y, por supuesto, puedes jugar con las firmas de varias maneras. El curry
de Ramda podría ayudar aquí. Tal vez queremos esto:
const foo = (f, g) => (x) => (y) => g (x) (f (x) (y)) const h = foo (f, g)
o incluso más, esto:
const foo = curry ((f, g) => curry ((x, y) => g (x) (f (x) (y)))) const h = foo (f, g) // equivalent: `foo (f) (g)` h ('a', 'b') // equivalent: `h ('a') ('b')`
La sugerencia de customcommander funciona:
const f = (a) => (b) => `f (${a}, ${b})` const g = (a) => (c) => `g (${a}, ${c})` const h = compose (apply (pipe), ap ([f, g]), of) console .log (h ('a') ('b'))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script> <script> const {compose, apply, pipe, ap, of} = R </script>
Pero creo que no es tan comprensible como la versión JS vainilla más explícita.