2

有没有办法解除一个简单的功能,像这样

fn add(a:i32, b:i32) -> i32 {a+b}

操作Option(或任何其他单子类型),类似于ApplicativeHaskell

我知道这个解决方案:

pub fn add(a: Option<i32>, b: Option<i32>) -> Option<i32> {
  Some(a? + b?)
}

但这需要我实际编写一个单独的函数,该Option函数与一元类型的参数和返回值

// something like this
let func = Option::lift2(add) //example, not working code                         

我显然在想Haskell,也许有更惯用的方式来做到这一点Rust

4

1 回答 1

3

你可以从这个开始:

fn lift<A, B, C>(f: impl Fn(A, B)->C) -> impl Fn(Option<A>, Option<B>)->Option<C> {
    move |oa, ob| {
        match (oa, ob) {
            (Some(a), Some(b)) => Some(f(a,b)),
            _ => None,
        }
    }
}

或者,为了缩短:

fn lift<A, B, C>(f: impl Fn(A, B)->C) -> impl Fn(Option<A>, Option<B>)->Option<C> {
    move |a, b| Some(f(a?, b?))
}

FnMut请注意,对于and ,您可能也需要类似的东西FnOnce

此外,上述内容仍然绑定到Option,而不是一般的单子事物,这在 Rust 中模拟非常麻烦(如果可能的话)。

于 2020-08-05T08:18:36.960 回答