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

时间:2016-02-07 16:26:03

标签: sml smlnj

这里的第一个问题,只是想作为序言,我做了几个查询,虽然我发现了多个措辞相似但我发现没有人提出或回答我的问题(据我所知)。 / p>

我正在使用SML进行课堂作业,因此我将留下一些细节,以便我自己解决问题。我在SML中定义了以下类型:

- type Env = string -> int;

本质上,Env类型应该是一个允许从字符串映射到int的函数 - 它是一个简单的环境方案。创建一个能够实现这一目标的功能,即:

,这是微不足道的
- fun foo (s:string) = 10; (*simple example*)

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

如果需要澄清,请询问,我会尝试更简洁。

3 个答案:

答案 0 :(得分:2)

  

原因是我最终需要创建一个返回值为Env类型函数的函数,我不知道如何执行此操作。

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

fun fooFactory arg : Env = ...

答案 1 :(得分:1)

您可以使用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

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

答案 2 :(得分:1)

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

以下是对您提问的两种解释:

  

如何创建一个返回 string→int 函数的函数?

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

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)
  

如何确保类型签名明确指出 ...→Env 而不是 ... 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