functional-programming - 标准 ML 风格:可变阴影是好的风格吗?
问题描述
在标准 ML 中,一般情况下是否有变量阴影,特别是在模式匹配可接受的情况下?对于这个玩具示例:
case xs of
[] => 0
| x::xs => x + sum xs
以下是更好的风格吗?
fun sum(xs) =
case xs of
[] => 0
| x::xs' => x + sum xs'
如果没有阴影,就必须选择不同的名称,这会使代码混乱,尤其是在使用嵌套模式、let
函数绑定和其他语言结构时。谢谢!
解决方案
可变阴影是好风格吗?
不。
但也不xs
是xs'
很好:它们具有相同的类型,因此很容易意外地使用一种而不是另一种。在您的情况下,这可能会导致无限递归,并且很快就会被检测到。但在其他情况下,它可能会导致更微妙的错误。这个建议并不是函数式编程特有的。
编辑:总的来说,我包括 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
将包含未剥离的空白,message
而classify
函数的则不会。因此,不是有多个message
s,一个有空格,另一个没有空格,而是将它们放在不同的函数范围内,这些函数执行不同的操作。
推荐阅读
- php - PHP - MySql:如何在 db 中存储来自 [输入文本] 和 [下拉值] 的值
- java - 无法弄清楚为什么此测试在向 ArrayList 添加项目时失败
- java - 如何在 java 8 中使用 IntStream 返回一个升序数组列表?
- python - python pandas按值计数重新标记值
- angular - 如何在打字稿(Angular)中实现同步功能
- hasura - 类型 query_root 必须定义一个或多个字段
- c# - 当我保存一个对象时,NHibernate 尝试将对象保存在 id=0 的数据库中
- python - 如何删除文件的特定最后两行?
- go - 如何在golang中将切片“附加”或“复制”到二维切片?
- javascript - Firebase 函数:根据数组元素发送多个通知