2011-06-12 38 views
0

我是一個newby。我寫下面的代碼。Ml語法錯誤,如何驗證代碼錯誤?

Delay(e) == fn() => e 
Force(e) == e() 

fun time_consuming(n) = 
    let fun tak(x, y, z) = if x <= y then y 
       else tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y)) 
    in   
fun tak(3*n, 2*n, n) 
funend; 
fun fib(n) = if n=0 orelse n=1 then 1 else fib(n-1) + fib(n-2); 
fun odd(n) = (n mod 2) = 1; 
fun f(x, y) = if odd(x) then 1 else fib(y); 
f(fib(9), time_consuming(9)); 

fun lazy_f(x, y) = if odd(x) then 1 else fib(y()); 
lazy_f(fib(9), fn() => (time_consuming(9))); 

這是懶惰的評估代碼。
但它有一些錯誤。

lazy.sml:1.13 Error: syntax error: inserting LPAREN
lazy.sml:4.2 Error: syntax error: inserting LET
lazy.sml:12.44 Error: syntax error: replacing SEMICOLON with EQUALOP
lazy.sml:15.21 Error: syntax error: inserting LPAREN
lazy.sml:17.1 Error: syntax error found at EOF

這些錯誤是什麼意思?

回答

4

在SML中,錯誤通常會級聯,也就是說,一個錯誤會導致錯誤發生後的錯誤負載。因此,一個好的策略是隻查看第一個錯誤,糾正錯誤並重試代碼。

如果我們看一下你的第一個錯誤:

lazy.sml:1.13 Error: syntax error: inserting LPAREN 

,我們可以看到,它是由第一線造成的。如果我們看一下,這是如何解釋sml;採用Delay函數,將e作爲參數,並得到一個新的函數。以此函數併發送==作爲參數,並獲得另一個函數,lambda函數fn() => e傳遞給它。然而,SML語法規定,爲了將lambda函數作爲參數傳遞,它們必須被包含,因此它會發布缺少左邊缺少的錯誤,這被錯誤地寫爲「插入LPAREN」。

但是,我沒有看到前兩行的目的是什麼,因爲其餘的代碼是獨立於它的,並且在語法上也幾乎正確,所以現在我只是將它們註釋掉(用「 (*」和‘*)’

讓我們運行新的代碼,並期待在第一個新的錯誤:

lazy.sml:7.4-8.4 Error: syntax error: deleting IN FUN 

現在我們將注意力轉移到第八行,並看到它和第九名錯誤地以「fun」爲前綴,我們將第八行和第九行的「fun」替換爲空格,然後再次運行。

現在,它的工作原理!這是工作代碼:

(* Delay(e) == fn() => e *) 
(* Force(e) == e() *) 

fun time_consuming(n) = 
    let fun tak(x, y, z) = if x <= y then y 
       else tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y)) 
    in   
     tak(3*n, 2*n, n) 
    end; 
fun fib(n) = if n=0 orelse n=1 then 1 else fib(n-1) + fib(n-2); 
fun odd(n) = (n mod 2) = 1; 
fun f(x, y) = if odd(x) then 1 else fib(y); 
f(fib(9), time_consuming(9)); 

fun lazy_f(x, y) = if odd(x) then 1 else fib(y()); 
lazy_f(fib(9), fn() => (time_consuming(9))); 

正如你可以看到,有比錯誤更錯誤,我希望你已經瞭解到解碼錯誤信息的含義是沒有必要的,並且簡單地查看位置的第一個錯誤往往足以認識到什麼是錯誤的。