我目前正在自学函数编程。
我正在尝试翻译以下内容:
(define a 3)
(define b (+ a 1))
(* (cond ((> a b) a)
((< a b) b)
(else -1))
(+ a 1))
进入JavaScript(使用Ramda)。
一个人可以使用嵌套三元组,但是我喜欢使用Ramda的cond
函数。这是我所做的:
const a = 3;
const b = 3 + 1;
cond([[() => a > b, () => a], [() => a < b, () => b], [T, () => -1]])() * (a + 1)
我遇到的问题是我不得不使用这些函数(例如() => 3
)而不是仅仅使用它们的值(例如a
)。
有什么办法可以避免这些功能?还是有另一种更好的方法(甚至没有Rambda)在JavaScript中做到这一点?
我想避免使用诸如if
,for
和switch
之类的语句。
解决此问题的另一种方法是使用:
import gt from "ramda/src/gt";
import lt from "ramda/src/lt";
const a = () => 3;
const b = () => a() + 1;
cond([[gt(a, b), a], [lt(a, b), b], [T, () => -1]])() * (a() + 1);
a
和b
较为复杂,因为它们总是必须被调用(请参阅a() + 1
)。
编辑:
由于某种原因,我将a
和b
定义为函数的最后一个代码不起作用
答案 0 :(得分:3)
Ramda是自动管理的,因此您可以使用某些参数来调用该函数,并重新获得一个新函数。例如:
const { pipe, cond, gt, lt, T, always, identity, multiply } = R
const a = 3
const b = 3 + 1
const fn = (a) => pipe(
cond([
[gt(a), always(a)],
[lt(a), identity],
[T, always(-1)]
]),
multiply(a + 1)
)
const result = fn(a)(b)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
答案 1 :(得分:2)
我认为您的工作有点误会。 cond
旨在为您提供功能。它实际上不是为创建表达式的标量值而设计的。当然,只需立即调用它生成的函数就可以做到这一点。但这不是重点。而且,它实际上并不意味着要使用null函数进行调用(除非为默认条件传递T
)。同样,您可以执行此操作,但是它与工具的功能相反。
尽管Ramda从LISP风格和ML风格的功能语言中汲取了灵感,尽管我个人更喜欢前者,但Ramda更接近ML世界,尤其是Haskell。因此,它旨在支持的主要活动是通过组合其他功能来构建功能。
如果我要解决此问题,则可能不会使用任何Ramda,而是选择以下内容:
const larger = (a, b) => (a > b) ? a : (b > a) ? b : -1
const foo = (a, b) => (a + 1) * larger(a, b)
foo(3, 4) //=> 16
foo(6, 3) //=> 42
foo(3, 3) //=> -4
或者,如果我不需要重复使用larger
,我可以像这样内联:
const foo = (a, b) => (a + 1) * ((a > b) ? a : (b > a) ? b : -1)
我当然可以用Ramda编写,而且没有点数:
const larger = cond([[gt, unapply(head)], [lt, unapply(last)], [T, always(-1)]])
const foo = converge(multiply, [inc, larger])
或者再次,我可以内联larger
,或将unapply(head)
替换为nthArg(0)
,将unapply(last)
替换为nthArg(1)
。
但是这些选项都不比原始选项可读性高。 Ramda在这里看不到任何内容。请注意,我是Ramda的忠实粉丝;我创办了图书馆,是图书馆的主要作者之一。但我认为不应将其用于所有问题。
答案 2 :(得分:1)
您不必在Scheme中将所有内容包装在thunk中(即不带参数的函数)的原因是,在您的情况下,cond
是一个宏,可以扩展为嵌套的if
:
(if (> a b) a
(if (< a b) b
-1))
所以没有,如果您想避免三元运算符并将所有内容包装在thunk中,那么使用香草JS就没有太多选择。
如果您不介意使用非标准JS,则可以使用带有Sweet.js ...的宏来实现cond
。