2011-03-07 43 views
2

我相信我在將我的第一個函數轉換爲僅使用賦值和循環方面處於正確的軌道。我知道這是針對函數式編程,但這正是教授想要的。SML - 列表替換函數的迭代翻譯

遞歸函數:

fun sub (x, y, []) = [] 
    | sub (x, y, z::zz) = if x = z then y::sub(x, y, zz) 
      else z::sub(x, y, zz); 

迭代翻譯:

fun sub2 (x, y, z) = 
    let val ret = ref []; val temp = z; 
    in 
     while !temp <> [] 
     do (if x = hd(!temp) then ret := !ret::y; temp := tl(!temp) 
      else ret := ret::hd(!temp); temp := tl(!temp)); 
     !ret; 
    end; 

我收到smlnj運行下面的錯誤。第一個與do相符,第二個在結尾。

Error: syntax error: replacing END with EQUALOP

Error: syntax error found at EOF

我很感謝幫助調試,或者更清晰的方式來完成這種迭代功能。

回答

4

爲什麼哦爲什麼他會這麼想?沒關係...

有很多問題。

  1. 您正在使用許多分號的方式,它們不是必需的。但這不是一個語法錯誤。
  2. 您在if語句中忘記了您的序列(exp1; exp2)周圍的括號。只允許在let..in..end表達式的「in」部分中排除括號。
  3. 您正在將temp引用爲ref類型(使用:=和!)。但是你沒有把它作爲參考。這意味着你的輸入變量z必須作爲參考給出。如果這是您的意圖,那麼它與原始子功能不匹配。
  4. 原始子函數將自身限制爲相等類型。但是,如果情況並非如此,那麼您的!temp <> null將作出限制。這是使用List.null函數代替的「最佳實踐」。
  5. 最後的!ret;的分號不應該在您的序列停止處,否則end將成爲失敗序列的一部分。
  6. 您忘記了解除引用ret或其他條件。
  7. 您已切換cons(:)的參數。缺點有'a * 'a list類型,因此需要一個元素,然後是一個元素列表。解決這個問題並且仍然保留元素順序的一種方法是使用append(@)函數,然後將該元素添加到單例列表中。然而,有很多方法可以更好地處理這個問題,因爲append函數在大列表上表現很差。

下面是一個可行的函數:

fun sub2 (x, y, z) = 
let 
    val ret = ref [] 
    val temp = ref z 
in 
    while not (null (!temp)) do 
    if x = hd(!temp) then 
     (ret := !ret @ [y]; 
     temp := tl(!temp)) 
    else 
     (ret := !ret @ [hd(!temp)]; 
     temp := tl (!temp)); 
    !ret 
end 

這裏可以改善的是,你總是使用相同的值更新的臨時一個顯而易見的事情。所以這可以被分解出來。然後,條件可以改變,而不是

fun sub2 (x, y, z) = 
    let 
     val ret = ref [] 
     val temp = ref z 
    in 
     while not (null (!temp)) do  
     (case x = hd(!temp) of 
      true => ret := y :: !ret 
     | false => ret := hd(!temp) :: !ret 
     ;temp := tl (!temp));   
     rev (!ret) 
    end 

特別注意如何的元素是不能添加數據,但所得到的列表中時,卻擺在了眼前,然後在最後的結果列表逆轉,以獲得正確的訂購。這會給你在大名單上更好的表現。然而,當你在SML中使用命令式風格時,還有更好的方法來做到這一點。

正如您已經看到的那樣,它可以以功能性的方式完成。但它也可以做得更簡單。考慮以下使用地圖。

fun sub3 (x, y, zs) = map (fn z => if z = x then y else z) zs 
+0

哇謝謝你。這些例子提供了很多。課堂上以一種奇怪的方式進行縮進和分號的使用。你介紹的不同功能將爲我提供極大的幫助。謝謝。 – Joel 2011-03-07 16:22:58