我正在尝试使用Java的某些功能来实现功能方法fold_right。我下面的代码可以工作,但是我真的不明白为什么为什么-我认为主要的问题是我对lambda在Java中的工作方式有点不确定(尤其是在使用它们时)与泛型)。例如,为什么我必须通过再次调用apply来调用在apply()中返回的lambda?我要上的课是在OCaml中教授的,对我来说,很容易理解OCaml在其标准库中具有的fold_right函数。我在Java中实现它的方式似乎更加笨拙和冗长-有人可以为我提供一些启示吗?
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
interface Func<A,B> {
B apply(A a);
}
class Add implements Func<Integer, Func<Integer,Integer>> {
@Override
public Func<Integer,Integer> apply(Integer a) {
return (b) -> a + b;
}
}
public class Fold {
public static <E> E fold(Func<E,Func<E,E>> f, E acc, LinkedList<E> lst) {
if (lst.isEmpty()) {
return acc;
} else {
LinkedList<E> listClone = (LinkedList<E>) lst.clone();
E theHead = listClone.removeFirst();
return (E) f.apply(theHead).apply((fold(f,acc,listClone)));
}
}
public static void main(String[] args) {
Integer[] nums = {1,2,3,4,5};
List<Integer> nums_lst = Arrays.asList(nums);
LinkedList<Integer> lst = new LinkedList<Integer>(nums_lst);
int result = Fold.fold(new Add(), 0, lst);
System.out.println(result); // should be 15
System.out.println(lst); // should be [1,2,3,4,5]
}
}
答案 0 :(得分:0)
稍微偏离主题,但是java具有内置的Function<T, R>
,也就是说,要了解代码的工作原理,让我们从<select>
<option value="Test1">test1</option>
<option value="Test2" selected="selected">test2</option>
<option value="Test3">test3</option>
</select>
<hr/>
接口开始:
Func<A, B>
因此,乍看之下,我们有两种类型,即interface Func<A,B> {
B apply(A a);
}
和A, B
方法告诉我,它接受类型为apply
的参数并返回类型为{{ 1}}。好的,现在转到A
类,该类将B
接口实现为:
Add
因此,根据我们先前的推理,在Func
中实现的Func<Integer, Func<Integer, Integer>>
方法将接受一个apply
并返回一个Add
。因此,当我们查看Integer
类旁边的Func<Integer, Integer>
方法时:(为简单起见,您可以将fold
视为Fold
)
E
请注意,由于您的Object
与public static <E> E fold(Func<E,Func<E,E>> f, E acc, LinkedList<E> lst) {
if (lst.isEmpty()) {
return acc;
} else {
LinkedList<E> listClone = (LinkedList<E>) lst.clone();
E theHead = listClone.removeFirst();
// A B <- remember the Func interface? here A is E and B is Func<E,E>
// f is a Func<E, Func<E, E>> that takes in an E and returns
// another Func<E, E> after calling apply thus
// breaking the steps:
// f.apply(E) <- we just called the apply method thus this should return a "B"
// Since B is a Func<E, E> we need to call apply to perform the operation
// onto the next element, which in this case is an addition. You can think
// of it as a -> b -> a + b.
// Now you played that nice trick of using recursion to call this function
// and traverse all elements till the end of the collection and accumulate
// all the intermediate results.
return (E) f.apply(theHead).apply((fold(f,acc,listClone)));
// the listClone is one element shorter in each recursion
// since you are removing the first element
}
}
的签名匹配,因此您可以将Func<A, B>
作为lambda传递,而无需实现java.util.Function
类的显式性: / p>
Add