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

The first question is here and I just want the preface that I made several queries, and although I found several questions that were formulated similarly, I did not find any that would ask or answer the question that I have (as far as I can judge).

I work in SML on assignment for a class, so I'm going to leave some details to solve this problem myself. I have the following type defined in SML:

- type Env = string -> int;

In essence, it is assumed that the Env type is a function that allows mapping from string to int - this is a simple environment diagram. It’s trivial to create a function that does this, that is:

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

But is there a way to declare this function as an "Env type"? The reason is that I need to create a function whose return value is a function of type Env, and I have no idea how to do this. I know that SML allows type smoothing, and I think that means that technically any function that has a type string -> intwill be synonymous with Env type for the program, but I would like something more explicit.

If you need clarification, please ask and I will try to be more concise.

+4
source share
3 answers

Ultimately, I need to create a function whose return value is a function of type Env, and I have no idea how to do this.

fun , Env, : Env ; :

fun fooFactory arg : Env = ...
+2

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

, ,

+1

Env ( type Env = ..., , , datatype Env = ... abstype Env = ...), , Env, , , β†’ int.

:

, β†’ 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 to ensure that the type signature explicitly indicates ... β†’ Env, and not ... string β†’ int?

  • Use 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))
    
  • Use abstype Env = ...:

    abstype Env = Env of string -> int
    with
        (* ... same as e.g. type Env = ..., except now the Env type is opaque ... *)
    end
    
  • Use modules:

    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
source

Source: https://habr.com/ru/post/1627672/


All Articles