2015-10-10 2 views
0

В настоящее время я изучаю sml, но у меня есть один вопрос, на который я не могу найти ответ. Я googled но все еще ничего не нашел.строка печати и вызывающая рекурсивная функция

Это мой код:

fun diamond(n) = 
    if(n=1) then (
    print("*") 
) else (

    print("*") 
    diamond(n-1) 

) 

diamond(5); 

Это не работает. Я хочу, чтобы код показывал столько же *, сколько и число n, и я хочу сделать это с рекурсией, но я не понимаю, как это сделать.

Я получаю сообщение об ошибке при попытке запустить этот код. Это ошибка:

Standard ML of New Jersey v110.78 [built: Thu Aug 20 19:23:18 2015] [opening a4_p2.sml] a4_p2.sml:8.5-9.17 Error: operator is not a function [tycon mismatch] operator: unit in expression: (print "*") diamond /usr/local/bin/sml: Fatal error -- Uncaught exception Error with 0 raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27

Спасибо

+0

Что такое ваш выход? – Academiphile

+0

@Zabari Я получаю сообщение об ошибке. Это ошибка: Стандарт ML Нью-Джерси v110.78 [построен: чт 20 авг 19:23:18 2015] [открытие a4_p2.sml] a4_p2.sml: 8.5-9.17 Ошибка: оператор не является функцией [tycon несовпадение] оператор: блок в выражении: (печать "*") алмаз /USR/местные/бен/SML: Фатальная ошибка - Uncaught ошибка исключения с 0 поднят на ../compiler/TopLevel/interact /evalloop.sml:66.19-66.27 – zeeks

ответ

2

Вы можете сделать побочные эффекты в ML с помощью «;» Он будет оценивать все, что есть до ';' и отбросить его результат.

fun diamond(n) = 
     if(n=1) 
     then (print "*"; 1) 
     else (print "*"; diamond(n-1)); 

    diamond(5); 

Причина ошибки в том, что ML является строго типизированным языком, хотя вам не нужно явно указать типы, он будет выводить их на основе факторов окружающей среды во время компиляции. По этой причине каждая оценка функций, таких как ifelse, должна оцениваться однозначным сингулярным типом.

Если вы разрешили сделать следующее:

 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 -> блок * внутр.

Таким образом, чтобы удовлетворить требование парадигмы строго типизированного функционального программирования, в котором мы стремимся создавать механизмы, которые оценивают один тип результата, нам необходимо сообщить компилятору, что некоторые инструкции должны выполняться как инструкции и не подлежат включению при наборе рассматриваемой функции. По этой причине вы используете ';' сообщать компилятору просто оценить эту инструкцию и отбросить ее результат от включения в оценку типа функции.

Насколько фактическая цель, то, следуя лучший способ написания функции, как алмаз типа Int -> строка:

fun diamond(n) = 
    if(n=1) 
    then "*" 
    else "*"^diamond(n-1); 

print(diamond(5)); 

выше способ является более для отладки.

+0

Спасибо, что это работает, но я не понимаю, почему 1 после печати «*»; – zeeks

+1

Это совсем не нужно. Я просто включил его, чтобы подчеркнуть иллюстрацию выполнения побочных эффектов. Это прекрасно работает: 'fun diamond (n) = if (n = 1) затем распечатать« * » еще (печать« * »; алмаз (n-1)); алмаз (5); ' –