如何使用类型推断在类型化语言中处理未使用的返回值?
How are unused returned values handled in typed languages with type inference?
具有类型推断的强类型语言如何处理未使用的返回值(预期类型是什么并不明显)?
这是一个发生在未类型化 Python 中的示例,当然不会被捕获:
list(map(lambda item: item.some_method, some_collection))
这里 item.some_method
是为了它的副作用而被调用的,所以正确的行是:
list(map(lambda item: item.some_method(), some_collection))
没有额外的约束,具有类型推断的强类型语言通常不会阻止第一个示例,因为它在技术上是有效的,正如您所指出的那样。有几种方法可以避免这种情况。
- 您可以显式注释地图的类型(或在强制类型等于某物的地方使用它)。如果使用了错误的变体,这将导致类型检查错误。
- 一些语言(例如 Rust)区分
map
和 for_each
,后者应该是 impure/effectful。如果在第一个示例中使用 for_each
,编译将失败,因为 lambda item: item.some_method
的类型是 A -> () -> ()
,而不是 A -> ()
。但是,没有什么可以阻止您在这里使用 map
。
- 一些语言(例如 Haskell)区分 impure/effectful 值和 pure/effectless 值。在此设置中,
map
应采用纯 lambda(使 lambda item: item.some_method()
无效),而 for_each
应采用不纯的 lambda(使 lambda item: item.some_method
无效的)。这是使用 monads 强制执行的,它充当一个标记,告诉类型系统一个值是不纯的(例如,类型 IO(A)
代表一个有效的 A
类型)。
- 一些语言(例如 Rust)允许跟踪值的使用和注释函数以强制它们的 return 值以某种方式成为 "used"。如果
map
以这种方式注释 #[must_use]
,则必须使用其 return 值,这会提醒您 lambda item: item.some_method
的不正确使用(因为 return map
的值将不会被使用)。在 Rust 中,单元类型 ()
自动为 "used",理论上这可以扩展为包括 [()]
,在这种情况下正确的代码 lambda item: item.some_method()
可以正常工作。
具有类型推断的强类型语言如何处理未使用的返回值(预期类型是什么并不明显)?
这是一个发生在未类型化 Python 中的示例,当然不会被捕获:
list(map(lambda item: item.some_method, some_collection))
这里 item.some_method
是为了它的副作用而被调用的,所以正确的行是:
list(map(lambda item: item.some_method(), some_collection))
没有额外的约束,具有类型推断的强类型语言通常不会阻止第一个示例,因为它在技术上是有效的,正如您所指出的那样。有几种方法可以避免这种情况。
- 您可以显式注释地图的类型(或在强制类型等于某物的地方使用它)。如果使用了错误的变体,这将导致类型检查错误。
- 一些语言(例如 Rust)区分
map
和for_each
,后者应该是 impure/effectful。如果在第一个示例中使用for_each
,编译将失败,因为lambda item: item.some_method
的类型是A -> () -> ()
,而不是A -> ()
。但是,没有什么可以阻止您在这里使用map
。 - 一些语言(例如 Haskell)区分 impure/effectful 值和 pure/effectless 值。在此设置中,
map
应采用纯 lambda(使lambda item: item.some_method()
无效),而for_each
应采用不纯的 lambda(使lambda item: item.some_method
无效的)。这是使用 monads 强制执行的,它充当一个标记,告诉类型系统一个值是不纯的(例如,类型IO(A)
代表一个有效的A
类型)。 - 一些语言(例如 Rust)允许跟踪值的使用和注释函数以强制它们的 return 值以某种方式成为 "used"。如果
map
以这种方式注释#[must_use]
,则必须使用其 return 值,这会提醒您lambda item: item.some_method
的不正确使用(因为 returnmap
的值将不会被使用)。在 Rust 中,单元类型()
自动为 "used",理论上这可以扩展为包括[()]
,在这种情况下正确的代码lambda item: item.some_method()
可以正常工作。