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语言中创建私有方法,只是作用域是包含函数而不是包含对象。这很卫生。