Objective C中的延迟数据类型

phw*_*hwd 6 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)
Run Code Online (Sandbox Code Playgroud)

我知道闭包可以使用Blocks编写,

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};
Run Code Online (Sandbox Code Playgroud)

所以我认为我可以将它用作函数参数.下一步将是如何使用没有实参数的函数(单位值,例如在SML中fn () =>)和创建惰性数据类型如上所述.

这是可能的还是我应该采用另一种更明显的方式?

最终目标是模拟SML中的暂停计算行为,

let val x = Susp(fn () => horribleComp(345))
in 
   force(x) + force(x)
end
Run Code Online (Sandbox Code Playgroud)

其中force(x)是

fun force (Susp(f)) = f ()
Run Code Online (Sandbox Code Playgroud)

Jon*_*ing 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
Run Code Online (Sandbox Code Playgroud)

这是很多样板,但无论如何.然后,您可以像这样使用它:

id x = [Susp withBlock:^{ return someComputation(); }];
id result = [[x force] plus:[x force]];
// assuming the result of your computation has -plus:
Run Code Online (Sandbox Code Playgroud)

但这一切都很愚蠢,因为对于你正在做的事情,你真的不需要其他数据类型.只需使用块作为您的数据类型:

typedef id (^SuspVal)(void);
SuspVal x = ^{ return complicatedThing; };
id result = [x() plus:x()];
Run Code Online (Sandbox Code Playgroud)

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

干杯!