在SML中,以下内容可用于建模延迟编程,
// Have a datatype to wrap a computation
datatype 'a susp = Susp of (unit -> 'a)
// A function to hold the computation
fun delay(f ) = Susp(f)
我知道可以使用Blocks,
编写闭包int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
所以我认为我可以将它用作函数参数。下一步是如何使用没有真实参数的函数(unit value,例如在SML fn () =>
中)并创建惰性数据类型如上所述。
这是可能的还是我应该采用另一种更明显的方式?
最终目标是模拟来自SML的暂停计算行为,
let val x = Susp(fn () => horribleComp(345))
in
force(x) + force(x)
end
其中force(x)是
fun force (Susp(f)) = f ()
答案 0 :(得分:5)
很酷的问题!
你可以在Objective-C中实现一个惰性容器,如下所示(但你可能不应该,见下文):
typedef id (^SuspBlock)(void);
@interface Susp : NSObjecti
- (id)initWithBlock:(SuspBlock)block;
+ (id)withBlock:(SuspBlock)block;
- (id)force;
@end
// -----
@interface Susp ()
@property (nonatomic, copy) SuspBlock _block;
@end
@implementation Susp
@synthesize _block;
- (id)initWithBlock:(SuspBlock)block {
self = [super init];
if (self != nil) {
self._block = block;
}
return self
}
+ (id)withBlock:(SuspBlock)block {
return [[[self alloc] initWithBlock:bloc] autorelease];
}
- (id)force {
return self._block();
}
- (void)dealloc {
self._block = nil;
[super dealloc];
}
@end
这是很多样板,但无论如何。然后,您可以像这样使用它:
id x = [Susp withBlock:^{ return someComputation(); }];
id result = [[x force] plus:[x force]];
// assuming the result of your computation has -plus:
但这一切都很愚蠢,因为对于你正在做的事情,你真的不需要其他数据类型。只需使用块作为您的数据类型:
typedef id (^SuspVal)(void);
SuspVal x = ^{ return complicatedThing; };
id result = [x() plus:x()];
这是一种更紧凑,惯用的方式,这就是我的建议。除非你需要为懒惰的对象添加超出块的基本实用程序的进一步语义,否则你不应该不必要地包装它们。
干杯!