Я хочу, чтобы моя функция возвращала любые необъявленные переменные.
например
fun minus (x, y) = x-y;
Если я получаю ввод «минус (1, a)», но «a» не объявляется, я хочу, чтобы имя «a» было увеличено.
Как мне это сделать?
sml не использует динамическую область видимости. Он может просматривать только те переменные, которые связаны в позиции определения.
@molbdnilo Я думаю, что "получить ввод" здесь означает просто аргументы.
Если вы не реализуете интерпретатор, SML вызовет ошибку перед вызовом вашей функции. Функции не передаются имена или переменные, ей передаются значения.
Если a
является необъявленной привязкой, SML не скомпилирует такую программу:
- fun minus (x, y) = x-y;
> val minus = fn : int * int -> int
- minus (1, a);
! Toplevel input:
! minus (1, a);
! ^
! Unbound value identifier: a
Это ошибка компиляции, а не исключение времени выполнения. Получение исключения времени выполнения из-за отсутствия привязки значения - это то, чего вы можете достичь в динамически типизированных языках, например Python. Как говорит molbdnilo, вам нужно реализовать интерпретатор в SML, чтобы добиться такого динамического поведения. Например:
datatype expr = Add of expr * expr
| Sub of expr * expr
| Int of int
| Var of string
exception UnknownVar of string
fun lookup s [] = raise UnknownVar s
| lookup s ((t,x)::vtable) = if s = t then x else lookup s vtable
fun eval vtable (Add (e1, e2)) = eval vtable e1 + eval vtable e2
| eval vtable (Sub (e1, e2)) = eval vtable e1 - eval vtable e2
| eval vtable (Int x) = x
| eval vtable (Var s) = lookup s vtable
Сначала запускаем этот интерпретатор для получения правильного результата, а затем - ошибку:
- eval [("foo",3),("bar",2)] (Sub (Var "foo", Var "bar"));
> val it = 1 : int
- eval [("foo",3)] (Sub (Var "foo", Var "bar"));
! Uncaught exception:
! UnknownVar "bar"
Это исключение времени выполнения из-за отсутствия переменной.
Здесь "bar"
- это строка, а не идентификатор SML.
Это всего лишь идентификатор в интерпретируемой среде.
Что вы подразумеваете под "получить ввод"? Вы реализуете переводчика?