Mã cung cấp lỗi là ideone here, xin lỗi tôi đã không thể đưa ra một ví dụ tối thiểu hơn.Lỗi Groovy khi currying
Vì nó hơi dài, tôi sẽ giải thích.
Lớp Unfoldr
và chức năng unfoldr
về cơ bản đối với những gì unfoldr
làm trong Haskell, tạo danh sách. Nhưng trong trường hợp này tôi tạo một trình lặp.
Chức năng map
một lần nữa, giống như map
trong Haskell. Nó được chuyển qua một trình lặp, gọi unfoldr
với trình lặp là "trạng thái" và tạo một trình lặp mới cho kết quả tương tự như trình lặp cũ nhưng với hàm đã cho áp dụng cho chúng.
splitlist
chia danh sách thành danh sách n
dài, tức là danh sách tách (2) ([1,2,3,4]) dẫn đến một trình lặp đầu tiên cung cấp [1,2] sau đó [3,4].
currify
có chức năng và cho phép áp dụng một phần chức năng đó. Ví dụ,
f = currify { a, b -> a + b }
Phương tiện f (2,3) = 5, f (2) (3) = 5, và f (2) là một đóng cửa có thêm 2. Tôi nhận này từ và câu trả lời cho this question .
Việc đóng băng một sự kết thúc đối số sẽ không thực sự làm gì với nó và hoạt động giống như chức năng nhận diện trên đó.
Cuối cùng, tôi đã ghi đè toán tử >>
trên trình vòng lặp để tôi có thể sử dụng nó về cơ bản giống như một đường ống.
Câu hỏi của tôi là tại sao dòng F:
không thành công, nhưng dòng A-E
tất cả đều thành công?
Mã (dài) ở đây và giống như tôi đã nói, cũng trên ideone.
@groovy.transform.TypeChecked
class Unfoldr<A,B> implements java.util.Iterator<A>
{
public Unfoldr(Closure<Object[]> f, B init)
{
this.f = f;
this.state = f(init);
}
public synchronized A next() throws java.util.NoSuchElementException
{
if (hasNext())
{
A curr = state[0];
state = f(state[1]);
return curr;
}
else
{
throw new java.util.NoSuchElementException();
}
}
public synchronized boolean hasNext()
{
return state != null;
}
public void remove() { throw UnsupportedOperationException; }
private Closure<Object[]> f;
private Object[] state;
}
def currify(fn) {
{ Object... args ->
if (args.size() == fn.maximumNumberOfParameters) {
fn(*args)
} else {
currify(fn.curry(*args))
}
}
};
def unfoldr = currify { f, init -> new Unfoldr(f, init) };
def map = currify { f, l -> unfoldr({ l2 -> if (l2.hasNext()) { def e = l2.next(); return [f(e), l2]} else { return null; } } , l.iterator())}
def splitlist = currify {
n, l ->
unfoldr(
{
l2 ->
try
{
def a = new Object[n];
for (i in 0..(n-1))
{
a[i] = l2.next();
}
return [a, l2];
}
catch (java.util.NoSuchElementException e)
{
return null;
}
},
l
)
};
Iterator.metaClass.rightShift = { PrintStream os -> delegate.each({ x -> os.println(x) }) }
Iterator.metaClass.rightShift = { Closure f -> f(delegate) }
id = { x -> x }
f = currify { x -> x }
println "A: "
[[1,2],[3,4]].iterator() >> System.out
println "B: "
[1,2,3,4].iterator() >> splitlist(2) >> System.out
println "C: "
[[1,2],[3,4]].iterator() >> map(id) >> System.out
println "D: "
[1,2,3,4].iterator() >> splitlist(2) >> map(id) >> System.out
println "E: "
[[1,2],[3,4]].iterator() >> map(f) >> System.out
println "F: "
[1,2,3,4].iterator() >> splitlist(2) >> map(f) >> System.out
Output:
A:
[1, 2]
[3, 4]
B:
[1, 2]
[3, 4]
C:
[1, 2]
[3, 4]
D:
[1, 2]
[3, 4]
E:
[1, 2]
[3, 4]
F:
Caught: java.lang.IllegalArgumentException: Can't curry 2 arguments for a closure with 1 parameters.
java.lang.IllegalArgumentException: Can't curry 2 arguments for a closure with 1 parameters.
at prog$_currify_closure8.doCall(prog.groovy:42)
at prog$_run_closure2_closure9.doCall(prog.groovy:49)
at Unfoldr.<init>(prog.groovy:8)
at prog$_run_closure1.doCall(prog.groovy:47)
at prog$_currify_closure8.doCall(prog.groovy:40)
at prog$_run_closure2.doCall(prog.groovy:49)
at prog$_currify_closure8.doCall(prog.groovy:40)
at prog$_run_closure5.doCall(prog.groovy:75)
at prog.run(prog.groovy:91)
tôi đã mở một câu hỏi mà tôi tin rằng đã bị cô lập vấn đề, liên kết là: http://stackoverflow.com/questions/16890893/groovy-same-parameters-different-results Tôi sẽ trao phần thưởng này cho một câu trả lời ở đó, chỉ cần đưa ra nhận xét ở đây. – Clinton