Достижение лени и запоминания - PullRequest
2 голосов
/ 17 января 2020

Лень является краеугольным камнем в книге «Чисто функциональные структуры данных», но не совсем ясно, как он ее получает, по крайней мере, мне. Я думал, что мне нужно только написать:

datatype 'a susp = $ of 'a
fun force ($x) = x
fun plus (x, y) = $case (x, y) of ($m, $n) => m + n

Но потом я получаю ошибку:

- use "ch4.sml";;
[opening ch4.sml]
ch4.sml:3.20 Error: syntax error: inserting  ORELSE
[unexpected exception: Compile]

uncaught exception Compile [Compile: "syntax error"]
raised at: ../compiler/Parse/main/smlfile.sml:19.24-19.46
../compiler/TopLevel/interact/evalloop.sml:45.54
../compiler/TopLevel/interact/evalloop.sml:306.20-306.23
../compiler/TopLevel/interact/interact.sml:65.13-65.16

Я попытался изменить функцию на

fun plus (x, y) = $(print "Evaluating...\n"; force x + force y)

Но вызов его с помощью plus ($4, $5) оценил его и не запомнил, потому что он возвращает $ 9 вместо $ plus(force $4, force $5), и он напечатал Evaluating... оба раза.

- plus ($4, $5);;
Evaluating...
val it = $ 9 : int susp
- plus ($4, $5);;
Evaluating...
val it = $ 9 : int susp

Я также хотел бы получить ключевое слово lazy, но я не уверен, поддерживает ли это SML в Нью-Джерси, было ли оно реализовано Крисом Окасаки, или оно было вручную отключено. Ключевое слово подсвечивается в моем редакторе, но при написании

fun lazy plus ($x, $y) = $ (x + y)

я получаю, что lazy - это функция, принимающая два параметра plus и ($x, $y) в соответствии с типом:

val lazy = fn : 'a -> int susp * int susp -> int susp


Мой вопрос сводится к Как мне получить лень и памятку в SML Нью-Джерси?

1 Ответ

3 голосов
/ 20 января 2020

Вам нужно включить лень и добавить несколько скобок ($ в книге имеет особые правила синтаксического анализа):

Standard ML of New Jersey v110.83 [built: Thu May 31 09:04:19 2018]
- Control.lazysml := true;
[autoloading]
[ ... boring details ...] 
[autoloading done]
val it = () : unit
- open Lazy;
[autoloading]
[autoloading done]
opening Lazy

  datatype 'a susp = $ of 'a
- fun plus (x, y) = $(case (x, y) of ($m, $n) => m + n);
val plus = fn : int susp * int susp -> int susp
-  val x = plus($4, $5);
val x = $$ : int susp
- fun force ($x) = x;
val force = fn : 'a susp -> 'a
- force x;
val it = 9 : int
- fun lazy plus ($x, $y) = $ (x + y);
val plus = fn : int susp * int susp -> int susp
val plus_ = fn : int susp * int susp -> int

Обратите внимание, что это не запоминает plus.

...