Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 使用模式匹配的SML-交替和_List_Sml - Fatal编程技术网

List 使用模式匹配的SML-交替和

List 使用模式匹配的SML-交替和,list,sml,List,Sml,我正在编写一个程序,它接受int列表并返回它们的交替和的值 Input: [1,2,3,4] Output: 1 + (-2) + 3 + (-4) 下面是我试图为此编写的代码,但我不断收到错误语法错误:插入ORELSE 我的if-then-else语句看起来是正确的,所以我不确定是什么导致了错误 fun alternate([]) = 0 | alternate(x::xs, count) = count = count + 1 if count mod

我正在编写一个程序,它接受
int
列表并返回它们的交替和的值

Input: [1,2,3,4]
Output: 1 + (-2) + 3 + (-4)
下面是我试图为此编写的代码,但我不断收到错误
语法错误:插入ORELSE

我的
if-then-else
语句看起来是正确的,所以我不确定是什么导致了错误

fun alternate([]) = 0
  | alternate(x::xs, count) = 
        count = count + 1
        if count mod 2 == 0 then (~x) + alternate(xs)
        else x + alternate(xs)

此错误是由于
count=count+1
如果。。。否则…
是多个表达式。如果要执行多个表达式,可以编写如下代码:

(expression1;
 expression2;
     ...
 expressionN);
fun alternate([]) = 0
  | alternate(x::xs) =
      let 
        fun alt([], count) = 0
          | alt(x::xs, count) =
              if count mod 2 = 0 then x + alt(xs, count+1)
              else (~x) + alt(xs, count+1)
      in 
        alt(x::xs, 0)
      end;
代码中还有两个错误。
1.函数的不同模式子句中的参数类型不同
alternate

2.在SML中,
=
表示相等,而不是
=

因此,正确的解决方案可能如下所示:

(expression1;
 expression2;
     ...
 expressionN);
fun alternate([]) = 0
  | alternate(x::xs) =
      let 
        fun alt([], count) = 0
          | alt(x::xs, count) =
              if count mod 2 = 0 then x + alt(xs, count+1)
              else (~x) + alt(xs, count+1)
      in 
        alt(x::xs, 0)
      end;
在此基础上,我建议实施
sum

val sum = foldr (op +) 0;
为了完整起见,从这里的答案复制
备用
函数,只需一个小错误:

fun alternate l =
   let
       fun alternate1 []      = []
         | alternate1 (x::xs) =   x  :: alternate2 xs
       and alternate2 []      = []
         | alternate2 (x::xs) = (~x) :: alternate1 xs
   in
       alternate1 l
   end
然后您可以非常简单地定义
alternate\u sum

val alternate_sum = sum o alternate
当然,会有人以表演的名义反对。Haskell能够在这些调用类型中执行毁林/融合优化,因为它知道一些关于函数纯度的信息;标准ML不需要这些优化,尽管有些实现可能会尝试,我不知道

这个特殊问题的开销可能是荒谬的,也可能不是荒谬的,但我认为不管怎样,它都是函数式编程原则的一个很好的例子:从更简单、无懈可击的行为建立复杂的行为。本版本中的“举证责任”几乎全部由
alternate
承担@SunsetRider的版本很好(它可能会执行得更好),但您可能会说代码更“单一”

另外,@SunsetRider的代码比它需要的要复杂一些,这个版本就足够了:

fun alternate l =
  let 
    fun alt([], count) = 0
      | alt(x::xs, count) =
          if count mod 2 = 0 then x + alt(xs, count+1)
          else (~x) + alt(xs, count+1)
  in 
    alt(l, 0)
  end
除了@sunsetrieder所说的之外,还有一条评论:一般来说,在函数语言中,
x=x+1
和其他突变都有点代码味道。您可以看到,在他们的代码中,他们多次使用
count+1
。从功能上考虑,重要的是表达式的计算对象,而不是变量的状态,因此传递的值是关键的。这可以追溯到这本优秀且被严重低估的书开头的极好的定义:

功能范式和命令范式从不同的角度运作。函数范式是基于表达式的计算和变量与值的绑定。程序的基本短语是表达式,计算表达式的目的是产生一个值。子表达式的求值顺序不影响结果值

命令式范例基于语句的执行,并具有一个语句可以在其中留下结果的存储。基本程序短语是语句;执行语句的目的是更改存储。语句的执行顺序确实会影响存储中的结果值。存储中的当前值集称为程序状态


let
子句中定义函数的目的是什么?@Delfini在
let
子句中定义的函数可以访问外部范围中绑定的所有内容,并且它们的可见性仅限于
let
子句的
部分。在本例中,它允许您将helper函数隐藏在API为public的函数的范围内。这有点像在OO语言中创建私有方法,只是作用域是包含函数而不是包含对象。这很卫生。