AmitKumarDas / Decisions

Apache License 2.0
10 stars 3 forks source link

Rust: Parametric polymorphism ~ combinator #176

Open AmitKumarDas opened 4 years ago

AmitKumarDas commented 4 years ago

:nerd_face: What? Polymorphism via parameters :bulb: Define the func signature with parameters & the actual type of parameters are defined at runtime

:nerd_face: Use parametric polymorphism to define combinators

fn map<F, T, A>(option: Option<T>, f: F) -> Option<A> where F: FnOnce(T) -> A {
    match option {
        None => None,
        Some(value) => Some(f(value)),
    }
}
// Searches `haystack` for the Unicode character `needle`. If one is found, the
// byte offset of the character is returned. Otherwise, `None` is returned.
fn find(haystack: &str, needle: char) -> Option<usize> {
    for (offset, c) in haystack.char_indices() {
        if c == needle {
            return Some(offset);
        }
    }
    None
}

:nerd_face: You abstract away an entire pattern via above polymorphism :volcano: This is known as combinator. Combine two unknown stuff together.

:male_detective: Option is defined as a std library :male_detective: Option has method w.r.t map that understands parametric polymorphism

// Returns the extension of the given file name, where the extension is defined
// as all characters following the first `.`.
// If `file_name` has no `.`, then `None` is returned.
fn extension(file_name: &str) -> Option<&str> {
    find(file_name, '.').map(|i| &file_name[i+1..])
}

:+1: entire error handling is handled via match

:nerd_face: More ways to handle error like the one shown below

fn unwrap_or<T>(option: Option<T>, default: T) -> T {
    match option {
        None => default,
        Some(value) => value,
    }
}