(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?
使用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))
使用abstype Env = ...
:
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
这里的第一个问题,只是想先说明一下,我做了几个查询,虽然我发现了多个措辞相似的问题,但我发现 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?
使用
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))
使用
abstype Env = ...
: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