ソモサン

私rohkiによる活動や読書の記録をつらつらと書くページです

Rust で Scala の continually ぽいもの

こんな感じ?

extern crate rand;

use rand::{Rng, thread_rng};
use std::usize;

pub struct Iterate<A> {
    func: A
}

impl<B, A> Iterator for Iterate<A> where A: FnMut() -> B {
    type Item = B;

    #[inline]
    fn next(&mut self) -> Option<B> { Some((self.func)()) }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
}

fn continually <A, B>(f: A) -> Iterate<A> where A: FnMut() -> B {
    Iterate { func: f }
}

fn main() {
    let mut rng = thread_rng();
    let a = std::iter::repeat(1).into_iter().map(|_| rng.gen::<u32>() % 100u32).take_while(|x| *x != 0u32).collect::<Vec<u32>>();

    let i = continually(|| rng.gen::<u32>() % 100u32).take_while(|x| x != &0u32).collect::<Vec<u32>>();
    println!("{:?}", a);
    println!("{:?}", i);
}

きっかけ

Scala の continually をみて、なるほど都度評価してくれるのか、と納得して、はて Rust では、となった次第。

書いてみて

std::iter::repeat もあるにはあるのですが、Clone trait を実装している必要があって、FnMut を渡せませんでした。たぶん。
ので、軽く書いてみたら動きました。でもありそう。見つけられてないだけで。
あと、表面だけまねてるので、いろいろ考えが足りてなさそうでもあります。
でも動いたから満足。