Turns out Option.and_then is literally Option's monadic bind. Both
do-notation and Haskell's list comprehensions (which generalize to monads
and I think are equivalent to Scala's for-comprehensions) actually just
desugar into calls to the monad's bind and return functions (Option's
return is just |x| Some(x) in Rust). I'm fairly certain Rust's macros can
handle both notational forms.

In general, monads require higher-kinded types because for a type to be a
monad it must take a type variable. That is, Option<T> and List<T> could be
monads, but int and TcpSocket can't be monads. So imagine we wanted to
define a trait Monad in Rust. It'd look something like:

trait Monad<T> {
    fn return(t: T) -> Self<T>;
    fn bind<U>(mt: Self<T>, f: |T| -> Self<U>) -> Self<U>;
}

Notice how Self takes a type parameter? That's not legal in current Rust.
We'd need to make sure that types implemented Monad take the right number
of type variables. This is where 'kinds' come in. Kinds are to types as
types are to values. Concrete types (those that don't take parameters) have
kind *. A type that has one type variable has kind * -> *, and so on. Kinds
like * -> * are called 'higher-kinds' and the types with those kinds are
'higher-kinded' types. Turns out Monad requires types of kind * -> *.
That's why Rust can't have general monads until we add higher kinded types.


On Tue, Feb 25, 2014 at 8:01 PM, Ziad Hatahet <[email protected]> wrote:

> On Tue, Feb 25, 2014 at 7:24 PM, Aran Donohue <[email protected]> wrote:
>>
>>
>>  Anyway, we like this feature and I'd be happy to see it adopted
>> elsewhere.
>>
>>
> There are few languages out there that take an approach like this,
> including Kotlin and Fantom. I agree it is a cool feature; however, the
> Option type is more general, and pattern matching is not the only way to
> deal with Option variables.
>
> map/map_or, and/and_then, or/or_else are some of the methods that can be
> called on Option in Rust, while still avoiding pattern matching. Referring
> to your `demo` function:
>
> // Rust syntax
> fn demo(c: Car, maybe_car: Option<Car>) {
>     c.start()
>     maybe_car.map(|car| car.start());
> }
>
> I am personally in favor of having something like Scala's monadic `for`
> construct. Apparently this feature needs Higher Kinded Types to be
> implemented in the compiler first. There has been a couple of Rust macro
> implementations that offer a stop gap though:
> https://mail.mozilla.org/pipermail/rust-dev/2013-May/004176.html
>
> --
> Ziad
>
>
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
>
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to