В let <decs> in <exp>
, <decs>
должно быть одно или несколько объявлений.
В вашем случае в строке 7 вы делаете y = 1
- обратите внимание, это не задание, а сравнение,То есть в C ++ это было бы эквивалентно выполнению y == 1
.Вы не можете назначить переменные без ссылки.(И вообще, вы хотите максимально избегать ref-переменных.) Вы можете сделать val y = 1
вместо него, и в этом случае вы создадите новое значение с именем y
, которое затеняет старую * 1009.* (но не изменяет его; вы создаете новое значение).
Аналогично, в строке 9 вы делаете x := 0
, который является не объявлением, а выражением, которое присваивает значение 0
к справочному значению x
, а затем возвращает единицу измерения.
Кроме того, вы можете делать несколько объявлений в своих операторах let, поэтому вам не нужно делать вложенность.
НаконецВы пишете p(x)
на верхнем уровне.Вы можете писать выражения только на верхнем уровне, если предшествующее объявление заканчивается точкой с запятой;в противном случае он считает, что это является частью декларации.То есть
val a = 5
6
интерпретируется как
val a = 5 6
Короче, вы можете переписать его так:
val x = ref 0;
fun p(y': int ref)=
let
val y = !y' (* this line might as well be deleted. *)
val y = 1
in
x := 0;
y' := y
end;
p(x)
Или, более короткая версия, так какSML имеет хороший вывод типа:
val x = ref 0;
fun p y' = (x := 0; y' := 1);
p x
Я скажу это, хотя;если вы пришли из языка, подобного C ++ или подобному, может быть соблазнительно использовать 'a ref
sa, но вы часто обнаружите, что сведение к минимуму их использования часто приводит к более чистому коду в SML.(И другие функциональные языки.)