2015-03-16 18 views
8

Tôi hy vọng tất cả các bạn đều ổn. Tôi đang triển khai điểm Y-combinator tại Cảng cố định và tôi đang gặp một số vấn đề với nó. Vâng, Y-Combinator có thể được xác định bởi các lambda-calculus như:Truy cập biến bên ngoài bên trong một khối và Y-combinator

Y = (λh.λF.F(λ x.((h(h))(F))(x))) (λh.λF.F(λ x.((h(h))(F))(x)))

Tôi đang cố gắng để áp dụng memoization với Y-Combinator bởi những câu hỏi hiệu suất. Triển khai hiện tại của tôi là:

Function YMem(bF, aCache) 
    Local xAnswer 
    If !lCache ; lCache := { } ; EndIf 
    Return { |Arg| Iif(aCache[ Arg ] ; 
     , /* then  */ aCache[ Arg ]; 
     , /* otherwise */ aCache[ Arg ] := ; 
      Eval(Eval(bF, { |N| Eval(Eval(YMem, bF, aCache), N) }), Arg)) } 

Về cơ bản, tôi không thể sử dụng câu lệnh bên trong khối, nhưng tôi có thể sử dụng biểu thức và nó hoạt động tốt. Tôi tránh một phép đệ quy vô hạn và giới hạn đi qua 0 đến vô hạn.

Cho đến thời điểm này, nó biên dịch tốt, nhưng khi tôi đang cố gắng truy cập một biến của một khối ngoài, Harbour đá tôi vào mặt!

Để kiểm tra việc thực hiện Y-Combinator, tôi cố gắng áp dụng một implemetation đơn giản của dãy Fibonacci, nhưng khi tôi quay trở lại một khối tiếp nhận một tham số G và ngầm trả về một khối tiếp nhận một tham số N, G becames không có sẵn cho tôi và trình biên dịch nói với tôi rằng "Biến khóa mã ngoài nằm ngoài tầm với".

Function Main 
    Local bFib := YMem({ |G| ; 
     { |N| ; 
      Iif(N == 0, 1, Iif(N == 1, 1, Eval(G, N - 1) + Eval(G, N - 2))); 
     } ; 
    }) 
    Return 

Điều này cũng sẽ cho phép tôi cắt khối. Câu hỏi của tôi là: làm thế nào tôi có thể truy cập một biến bên ngoài bên trong một khối, trong Harbor?

+0

@vittore Xin lỗi? –

Trả lời

4

Trong ngôn ngữ lập trình theo Harbor, Clipper và xBase, chặn không bao giờ có thể tham chiếu cho biến của khối chính. Các khối không bị đóng. Chúng tôi có thể đạt được điều đó bằng cách tạo kho lưu trữ địa phương và sử dụng chúng trong các khối nội bộ:

Function TestOuterScope 
    Local accA 
    Local bAdd := { |A| accA := A, { |B| accA + B } } 
    Return Eval(Eval(bAdd, 10), 20) 
Các vấn đề liên quan