首页 > 解决方案 > 标准 ML 风格:可变阴影是好的风格吗?

问题描述

在标准 ML 中,一般情况下是否有变量阴影,特别是在模式匹配可接受的情况下?对于这个玩具示例:

  case xs of
      [] => 0
    | x::xs => x + sum xs

以下是更好的风格吗?

fun sum(xs) =
  case xs of
      [] => 0
    | x::xs' => x + sum xs'

如果没有阴影,就必须选择不同的名称,这会使代码混乱,尤其是在使用嵌套模式、let函数绑定和其他语言结构时。谢谢!

标签: functional-programmingsmlml

解决方案


可变阴影是好风格吗?

不。

但也不xsxs'很好:它们具有相同的类型,因此很容易意外地使用一种而不是另一种。在您的情况下,这可能会导致无限递归,并且很快就会被检测到。但在其他情况下,它可能会导致更微妙的错误。这个建议并不是函数式编程特有的。

编辑:总的来说,我包括 molbdnilo 的建议y::ys

fun sum xs =
    case xs of
         [] => 0
       | y::ys => y + sum ys

另一种方法是仅模式匹配并绑定您实际需要的值。在您的sum示例中,除了拆分之外,您实际上不需要完整输入。所以你可以这样写

fun sum [] = 0
  | sum (x::xs) = x + sum xs

或者使用更隐式的模式匹配匹配:

val sum = foldl op+ 0

另一个例子,Exercism 的 Bob 练习,可以通过首先清理输入然后对其进行分类来解决:

datatype diction = Yelling | Asking | YellingAsking | Whatever

fun strip message = ...

fun classify message = ...

fun answer diction = ...

val response = answer o classify o strip

这里的message函数strip将包含未剥离的空白,messageclassify函数的则不会。因此,不是有多个messages,一个有空格,另一个没有空格,而是将它们放在不同的函数范围内,这些函数执行不同的操作。


推荐阅读