Вы можете вызвать побочные эффекты в ML, используя ';' Он будет оценивать все, что стоит перед ';' и отбросьте его результат.
fun diamond(n) =
if(n=1)
then (print "*"; 1)
else (print "*"; diamond(n-1));
diamond(5);
Причина ошибки заключается в том, что ML - это строго типизированный язык, который, хотя вам не нужно явно указывать типы, он будет определять их на основе факторов окружающей среды во время компиляции. По этой причине каждое вычисление функций, таких операторов, как if
else
, необходимо оценивать до однозначного единственного типа.
Если бы вам было разрешено делать следующее:
if(n=1)
then 1
else print "*";
тогда компилятор получит другую типизацию для веток then
и else
соответственно. Для ветви then
типом будет int -> int
, тогда как типом ветви else
будет int -> unit
. Такая дихотомия не допускается в строго типизированном языке.
Поскольку вам нужно оценить единичный тип, вы поймете, что ML не поддерживает выполнение блока инструкций, как мы обычно видим в других парадигмах, которые наивно перенесены в ML, будут отображать что-то вроде этого:
....
if(n=1)
then (print "1"
print "2"
)
else (print "3"
diamond(n-1)
)
...
потому что какой тип будет оценивать ветвь then? int -> unit
? Тогда как насчет другого оператора печати? Оператор должен возвращать единичный результат (даже составной), чтобы это не имело смысла. А что насчет int -> unit * unit
? Нет проблем с этим, за исключением того, что синтаксически вы не смогли передать кортеж компилятору.
По этой причине БУДЕТ работать следующее:
fun diamond(n) =
if(n=1)
then (print "a", 1) /* A tuple of the type unit * int */
else diamond(n-1);
diamond(5);
В этом случае у вас есть функция типа int -> unit * int.
Таким образом, чтобы удовлетворить требования парадигмы строго типизированного функционального программирования, где мы стремимся создать механизмы, которые оценивают один тип результата, нам, таким образом, необходимо сообщить компилятору, что определенные операторы должны выполняться как инструкции, а не быть включены в типизацию рассматриваемой функции. По этой причине вы используете ';' чтобы сообщить компилятору, чтобы он просто оценил этот оператор и исключил его результат из включения в оценку типа функции.
Что касается вашей фактической цели, следующий способ лучше написать функцию, алмаз как тип int -> string:
fun diamond(n) =
if(n=1)
then "*"
else "*" ^ diamond(n-1);
print( diamond(5) );
Вышеупомянутый способ больше подходит для целей отладки.
person
Kevin Johnson
schedule
10.10.2015