How to get the OUT value of my fashion monad?

For educational reasons, I am trying to implement possibly a monad in C ++ 14. My (perhaps too simplified) understanding of monads is that they allow you to define computation as a series of compositional function calls. The Wikipedia article on monads calls them “programmable semicolons” because they let you determine what happens between what would otherwise be a set of calls to a low-key function. Perhaps a monad is a monad that interrupts the calculation if a failure occurs.

template<class T>
struct maybe
{
    maybe( const T& t ) : argument( t ), valid( true ) {}
    maybe() : argument(), valid( false ) {}

    T argument;
    bool valid;
};

template<class T>
maybe<T> just( const T& t ) { return maybe<T>(t); }

template<class T>
maybe<T> nothing() { return maybe<T>(); }

auto terminal_maybe = [] ( auto term ) {
    return [=] ( auto func ) {
        return func( term );
    };
};

auto fmap_maybe = [] ( auto f ) {
    return [=] ( auto t ) {
        if( t.valid ) {
            try {
                t.argument = f( t.argument );
                printf("argument = %d\n",t.argument);
            }
            catch(...) {
                t.valid = false;
            }
        }

        return (t.valid) ? terminal_maybe( just( t.argument ) ) : terminal_maybe( nothing<decltype(t.argument)>() );
    };
};

int main( int argc, char* argv[] )
{
    auto plus_2 = [] ( auto arg ) { return arg + 2; };
    auto minus_2 = [] ( auto arg ) { return arg - 2; };

    maybe<int> forty = just(40);

    terminal_maybe(forty)
        (fmap_maybe( plus_2 ))
        (fmap_maybe( plus_2 ));

    printf("result = %d\n",forty.argument);

    return 0;
}

, ! ( printf, , ( 40 42, 42 44)). , OUT! terminal_maybe (auto &), return fmap ( terminal_maybe (t), , ). printf .

+4
1

, , FP.

auto unwrap = [](auto const &f) {
    return f;
};

int main( int argc, char* argv[] )
{
    auto plus_2 = [] ( auto arg ) { return arg + 2; };
    auto minus_2 = [] ( auto arg ) { return arg - 2; };

    maybe<int> forty = just(40);

    auto const &outv = terminal_maybe(forty)
        (fmap_maybe( plus_2 ))
        (fmap_maybe( plus_2 ))
        (unwrap);

    std::printf("result = %d\n",outv.argument);

    return 0;
}
+2

All Articles