2013-05-31 24 views
5

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) 
+0

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

Trả lời

0

Hình như dòng F không gây

def e = l2.next() 

lợi nhuận Object [] thay vì ArrayList

Các vấn đề liên quan