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

(SML)将类型定义为函数并创建此类型的函数,sml,smlnj,Sml,Smlnj,这里的第一个问题,我想先说明一下,我做了几个问题,虽然我发现了多个措辞类似的问题,但我没有发现有人问或回答我的问题(据我所知) 我在SML做一个课堂作业,所以我会留下一些细节,这样我可以自己解决这个问题。我在SML中定义了以下类型: - type Env = string -> int; 本质上,Env类型应该是一个允许从字符串映射到int的函数——这是一个简单的环境方案。创建一个函数来实现这一点非常简单,即: - fun foo (s:string) = 10; (*simple ex

这里的第一个问题,我想先说明一下,我做了几个问题,虽然我发现了多个措辞类似的问题,但我没有发现有人问或回答我的问题(据我所知)

我在SML做一个课堂作业,所以我会留下一些细节,这样我可以自己解决这个问题。我在SML中定义了以下类型:

- type Env = string -> int;
本质上,Env类型应该是一个允许从字符串映射到int的函数——这是一个简单的环境方案。创建一个函数来实现这一点非常简单,即:

- fun foo (s:string) = 10; (*simple example*)
但是有没有办法将这个函数声明为“Env类型”?原因是最终我需要创建一个返回值为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;
有点神秘的消息
错误:子句中的函数符号非法

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

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

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

fun fooFactory arg : Env = ...

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

以下是对你的问题的两种解释:

如何创建返回字符串的函数→ 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=…
  • 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))
    
    abstype Env = Env of string -> int
    with
        (* ... same as e.g. type Env = ..., except now the Env type is opaque ... *)
    end
    
  • 使用
    abstype 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))
    
    abstype Env = Env of string -> int
    with
        (* ... same as e.g. type Env = ..., except now the Env type is opaque ... *)
    end
    
  • 使用模块:

    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
    

  • +1.请注意,在
    foo_temp
    情况下,您可能应该使用
    local
    (甚至可以使用名称
    foo
    )。还要注意,在匿名函数的情况下,如果函数是递归的,则需要使用
    val rec
    。最后,请注意,您可以通过将
    val\ufoo=Env
    放在下一行来完成大致相同的事情。虽然下面的一些答案很有见地且具有解释性,但我很欣赏这一行的简洁性。谢谢你的帮助。