实现懒惰和记忆
Achieving laziness and memoization
Laziness 是 Purely Functional Data Structures 这本书的一块基石,但它并没有清楚地描述他是如何获得它的,至少对我来说是这样。
我以为我只需要写:
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 (, )
调用它评估了它并且没有记住它,因为它 returns $ 9
而不是 $ plus(force , force )
并且它打印了 Evaluating...
两者次。
- plus (, );;
Evaluating...
val it = $ 9 : int susp
- plus (, );;
Evaluating...
val it = $ 9 : int susp
我也想获取关键词lazy
,但不知道SML New Jersey是否支持,是Chris Okasaki实现的,还是人工去糖的。
关键字在我的编辑器中突出显示,但在编写
时
fun lazy plus ($x, $y) = $ (x + y)
我知道 lazy
是接受两个参数 plus
和 ($x, $y)
的函数,由类型给出:
val lazy = fn : 'a -> int susp * int susp -> int susp
我的问题归结为 如何在 SML New Jersey 中获得懒惰和记忆?
需要开启laziness,加上括号(书上的$
有奇特的解析规则):
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(, );
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
。
Laziness 是 Purely Functional Data Structures 这本书的一块基石,但它并没有清楚地描述他是如何获得它的,至少对我来说是这样。 我以为我只需要写:
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 (, )
调用它评估了它并且没有记住它,因为它 returns $ 9
而不是 $ plus(force , force )
并且它打印了 Evaluating...
两者次。
- plus (, );;
Evaluating...
val it = $ 9 : int susp
- plus (, );;
Evaluating...
val it = $ 9 : int susp
我也想获取关键词lazy
,但不知道SML New Jersey是否支持,是Chris Okasaki实现的,还是人工去糖的。
关键字在我的编辑器中突出显示,但在编写
fun lazy plus ($x, $y) = $ (x + y)
我知道 lazy
是接受两个参数 plus
和 ($x, $y)
的函数,由类型给出:
val lazy = fn : 'a -> int susp * int susp -> int susp
我的问题归结为 如何在 SML New Jersey 中获得懒惰和记忆?
需要开启laziness,加上括号(书上的$
有奇特的解析规则):
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(, );
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
。