2016-03-06 26 views
10

再帰的クロージャを返す関数を実装しようとしていますが、関数シグネチャでそれを表現する方法がわかりません。以下は、Pythonで動作する実装のコード例です。再帰的クロージャを返すための関数シグネチャ

def counter(state): 
    def handler(msg): 
     if msg == 'inc': 
      print state 
      return counter(state + 1) 

     if msg == 'dec': 
      print state 
      return counter(state - 1) 
    return handler 

c = counter(1) 
for x in range(1000000): 
    c = c('inc') 

と擬似コードfor Rustです。

enum Msg { 
    Inc, 
    Dec 
} 

fn counter(state: Int) -> ? { 
    move |msg| match msg { 
     Msg::Inc => counter(state + 1), 
     Msg::Dec => counter(state - 1), 
    } 
} 

答えて

11

錆が再帰的な型をサポートしているので、あなただけの独立した構造で再帰をエンコードする必要があります。

enum Msg { 
    Inc, 
    Dec, 
} 

// in this particular example Fn(Msg) -> F should work as well 
struct F(Box<FnMut(Msg) -> F>); 

fn counter(state: i32) -> F { 
    F(Box::new(move |msg| match msg { 
     Msg::Inc => { 
      println!("{}", state); 
      counter(state + 1) 
     } 
     Msg::Dec => { 
      println!("{}", state); 
      counter(state - 1) 
     } 
    })) 
} 

fn main() { 
    let mut c = counter(1); 
    for _ in 0..1000 { 
     c = c.0(Msg::Inc); 
    } 
} 

我々は、残念ながら、ここでボクシングを廃止することはできません - アンボクシングクロージャunnameable種類を持っているので、我々は、それらを構造体宣言の内部に名前を付けることができるようにするために、それらを特性オブジェクトにボックスする必要があります。