(SML) 将类型定义为函数并创建该类型的函数

(SML) Defining a type as a function and creating a function of this type

这里的第一个问题,只是想先说明一下,我做了几个查询,虽然我发现了多个措辞相似的问题,但我发现 none 提出或回答了我的问题(至我看得出来)。

我正在 SML 中为 class 分配任务,因此我将省略一些细节以便我自己解决问题。我在 SML 中定义了以下类型:

- type Env = string -> int;

本质上,Env 类型应该是一个允许从字符串映射到 int 的函数——这是一个简单的环境方案。创建一个执行此操作的函数就足够了,即:

- fun foo (s:string) = 10; (*simple example*)

但是有没有办法将此函数实际声明为 "Env type"?原因是最终我需要创建一个 return 值是 Env 类型函数的函数,我不知道如何执行它。我知道 SML 允许类型别名,我认为这意味着从技术上讲,任何具有类型 string -> int 的函数都将与程序的 Env 类型同义,但我想要更明确的东西。

如果需要说明,请询问,我会尽量简明扼要。

您可以使用 val 绑定而不是 fun 声明来让 SML 明确地将类型与函数相关联。要么像这样的两步过程:

- fun foo_temp (s:string) = 10;
val foo_temp = fn : string -> int

- val foo:Env = foo_temp;
val foo = fn : Env

或者您可以使用匿名函数:

 -val (foo:Env) = fn (s:string) => 10;
val foo = fn : Env

我不确定是否可以直接使用 fun 关键字来完成。例如,以下失败:

-fun (foo:Env) (s:string) = 10;

带有一些神秘的信息 Error: illegal function symbol in clause

也许还有其他一些我不熟悉的解决方法

The reason is eventually I need to create a function whose return value is an Env type function and I have no idea how to perform this.

当使用 fun 时,您可以通过在所有参数模式之后放置类型注释 : Env 来指定 return 类型为 Env;例如:

fun fooFactory arg : Env = ...

因为 Env 只是一个类型别名(使用 type Env = ... 而不是 datatype Env = ...abstype Env = ... 创建),创建一个 returns 的函数一个 Env 与创建一个 returns 一个 string → int 函数的函数完全相同。

对你的问题有两种解读:

How do I create a function that returns a string → int function?

有几种方法,这实际上取决于它应该做什么。但一些例子可能是:

val zero_env = fn s => 0
fun update_env env t x = fn s => if s = t then x else env s
fun add_env env t x = fn s => env s + (if s = t then x else 0)

How do I ensure that the type signature explicitly says ... → Env rather than ... string → int?

  1. 使用datatype Env = ...:

    datatype Env = Env of string -> int
    fun unEnv (Env f) = f
    val zero_env = Env (fn s => 0)
    fun update_env env t x = Env (fn s => if s = t then x else (unEnv env) s)
    fun add_env env t x = Env (fn s => (unEnv env) s + (if s = t then x else 0))
    
  2. 使用abstype Env = ...:

    abstype Env = Env of string -> int
    with
        (* ... same as e.g. type Env = ..., except now the Env type is opaque ... *)
    end
    
  3. 使用模块:

    signature ENV =
    sig
        type Env
        val zero_env : Env
        val update_env : Env -> string -> int -> Env
        val add_env : Env -> string -> int -> Env
        ...
    end
    
    structure FunctionalEnv : ENV =
    struct
        (* ... same as e.g. type Env = ..., except now the Env type is opaque ... *)
    end