reference - 签名中的 SML 多态引用

标签 reference functional-programming polymorphism sml

有没有办法在签名中制作多态引用常量?

这段代码可以编译,但不是我需要的:

signature NAME = sig
    type 'a name
    val empty : 'a name
end

structure Name :> NAME  = struct
    datatype 'a name = Nil | Val of 'a
    val empty = Nil
end

添加所需的引用:

signature NAME = sig
    type 'a name
    val empty : 'a name ref
end

structure Name :> NAME  = struct
    datatype 'a name = Nil | Val of 'a
    val empty = ref Nil
end

产生以下错误:

error: Structure does not match signature.
    Signature: val empty: 'a name ref
    Structure: val empty: 'a name ref
    Reason: Can't match 'a to 'a (Type variable is free in surrounding scope)
Found near struct datatype 'a name = Nil | Val of 'a  val empty = ref Nil end

最佳答案

这实际上与签名无关;如果您(在顶层)编写,您会遇到同样的问题:

val emptyListRef = ref nil
val emptyIntList = (! emptyListRef) : int list
val emptyStringList = (! emptyListRef) : string list

问题是 emptyListRef - 或者在您的情况下 empty - 不能是多态的。 (您的编译器声称 empty 具有类型 'a name ref,但它真正的意思是 empty 将具有 ?? name ref 形式的某种类型,并且尚未弄清楚 ?? 是什么。)

当您考虑到如果多态时,这个限制是有意义的,那么您就可以编写如下内容:

val () = empty := Val 3
val Val (x : string) = !empty

其中您设置empty来保存int Name,然后从中读取,就像它保存string Name一样。无法说服编译器相信您不会这样做。

一般规则是,只有当右侧采用几种简单形式之一时,值绑定(bind)才允许是多态的,例如构造函数的组合(除了ref!)和常量以及fn - 表达式,已知是安全的(因为它们不能启用上述不当行为)。该规则称为 value restriction ;您可以通过 Google 搜索该术语来获取更多信息。

关于reference - 签名中的 SML 多态引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44169816/

相关文章:

scala - 在 Scala 中将命令式 for 循环重写为声明式样式

java - 将字符串数组元素插入列表中

c++ - 引用是存储在堆上还是栈上?

c++ - 多态 C++ 引用

java - Java使用内部类的方法引用

concurrency - 函数式语言如何处理共享状态数据?

java - 从具有相同成员的列表中过滤对象

javascript - JavaScript 中的 "reference"?

c++ - 在父类的 vector 上调用子类的方法

haskell - 我想编写一个类似于Haskell中的`flip`的函数来摆脱lambda表达式。但我不能处理它的类型