8000 Add a `FromEither` trait · Issue #105 · rayon-rs/either · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Add a FromEither trait #105
Open
Open
@c3potheds

Description

@c3potheds

There is an into_inner() method on Either<T, T> that can "unwrap" the inner value as long as both arms have the same type.

This is useful, but a more generic conversion could be implemented for any Either<A, B> to any type T that implements From<A> + From<B>.

Such a trait would be simple to blanket implement:

pub trait FromEither<A, B> {
    fn from_either(either: Either<A, B>) -> Self;
}

impl<A, B, T> FromEither<A, B> for T
where
    T: From<A> + From<B>,
{
    fn from_either(either: Either<A, B>) -> Self {
        match either {
            Left(a) => Self::from(a),
            Right(b) => Self::from(b),
        }
    }
}

Programmers would rarely implement this directly, but rely on the blanket implementation to kick in when they've implemented From for each arm of an Either on their type.

Why would this be useful? Consider an Iterator of Either values. One may with to transform those values into another enum:

#[derive(Debug)]
struct A;
#[derive(Debug)]
struct B;
#[derive(Debug)]
enum C {
    A(A),
    B(B),
}

impl From<A> for C {
    fn from(a: A) -> Self {
        C::A(a)
    }
}

impl From<B> for C {
    fn from(b: B) -> Self {
        C::B(b)
    }
}

fn main() {
    [Left(A), Right(B), Left(A), Right(B)]
        .into_iter()
        .map(C::from_either)
        .for_each(|c| {
            println!("{c:?}");
        });
}

If the arms are the same, we could use Either::into_inner as the function passed to map(). FromEither is useful specifically if the arms are different but still convertible to a common type.

My current workaround is to use map(|ab| ab.either(C::from, C::from)) in situations like this, which works, but is a little more verbose than map(C::from_either).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0