【问题标题】:Point-free at top-level in Standard ML标准 ML 中的顶层无点
【发布时间】:2018-03-26 07:29:48
【问题描述】:

第一个和第二个flatMap 运行良好。为什么第三个不起作用?

fun flatMap f xs = List.concat(List.map f xs)
fun flatMap f = List.concat o List.map f
val flatMap = (fn mmp => List.concat o mmp) o List.map;

【问题讨论】:

标签: sml pointfree


【解决方案1】:

这是由于一个称为“值多态性”或“值限制”的规则。根据这条规则,如果表达式可能是“可扩展的”,则值声明不能创建多态绑定;也就是说,一个值声明只能创建一个多态绑定,前提是它符合一个高度受限的语法,以确保它不能创建引用单元格或异常名称。

在你的例子中,由于(fn mmp => List.concat o mmp) o List.map 调用函数o,它不是非扩展的; 知道o不会创建引用单元格或异常名称,但语法无法区分。

所以声明val flatMap = (fn mmp => List.concat o mmp) o List.map 仍然是允许的,但它不能创建多态绑定:它必须给flatMap 一个单态类型,例如(int -> real list) -> int list -> real list。 (注意:并非标准 ML 的所有实现都能在所有上下文中推断出所需的类型,因此您可能需要添加显式类型提示。)

此限制的存在是为了确保我们不会通过使用一种类型写入 ref 单元格并使用不同类型读取它,或者通过将一种类型包装在多态异常构造函数中并解包来隐式地从一种类型转换为另一种类型它使用不同的类型。例如,下面的程序被值限制禁止,但如果它们被允许,每个程序都会创建一个名为 garbage 的变量,类型为 string,该变量从 integer 17 初始化:

val refCell : 'a option ref =
  ref NONE

val () = refCell := SOME 17

val garbage : string =
  valOf (! refCell)
val (wrap : 'a -> exn, unwrap : exn -> 'a) =
  let
    exception EXN of 'a
  in
    (fn x => EXN x, fn EXN x => x)
  end

val garbage : string =
  unwrap (wrap 17)

更多信息:

  • "ValueRestriction" in the MLton documentation
  • "Value restriction" on the English Wikipedia
  • "Types and Type Checking" in SML/NJ's guide to converting programs from Standard ML '90 to Standard ML '97。 (Standard ML '90 有这个规则的不同版本,它更宽松——它会允许你的程序——但被认为“有些微妙”,在某些情况下“不愉快”,因此它在 Standard ML '97 中被替换。)
  • The Definition of Standard ML (Revised) (PDF) 的以下部分:
    • §4.7 “非扩展表达式”,第 21 页,定义了哪些表达式被视为“非扩展”(因此可用于多态值声明)。
    • §4.8 “闭包”,第 21-22 页,它定义了使绑定多态的操作;如果表达式可能是可扩展的,则此操作通过防止绑定变为多态来强制执行值限制。
    • 推理规则(15),第26页,使用上述操作;另见第 27 页的评论。
    • 关于推理规则 (20) 的注释,第 27 页,它解释了为什么上述操作不适用于异常声明。 (从技术上讲,这与价值限制有所不同;但没有这个价值限制将毫无用处。)
    • §G.4“值多态性”,第 105–106 页,讨论了与 Standard ML '90 相比的这一变化。

【讨论】:

    猜你喜欢
    • 2015-04-05
    • 2013-07-27
    • 1970-01-01
    • 2010-11-12
    • 2011-05-05
    • 2011-01-03
    • 1970-01-01
    • 2013-01-02
    • 2013-01-01
    相关资源
    最近更新 更多