Objective C中的延迟数据类型

时间:2011-05-09 18:21:27

标签: objective-c sml

在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 ()

1 个答案:

答案 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()];

这是一种更紧凑,惯用的方式,这就是我的建议。除非你需要为懒惰的对象添加超出块的基本实用程序的进一步语义,否则你不应该不必要地包装它们。

干杯!