2011-03-07 48 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