2011-05-09 90 views
6

在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 

其中力(x)是

fun force (Susp(f)) = f() 

回答

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

這就是繞了一個更加緊湊的,習慣的方法,它是我的建議。除非你需要增加更多的語義到超越塊的基本工具的懶惰對象上,否則你不應該不必要地包裝它們。

乾杯!

+1

謝謝我不知道你是否可以使用這樣的塊和typedef。我將首先嚐試後一種方式,如果需要與後續項目的模板一起工作。 – phwd 2011-05-09 19:48:25