Skip to content

Instantly share code, notes, and snippets.

@tcsavage
Forked from anonymous/Maybe.cpp
Created December 12, 2012 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tcsavage/4269050 to your computer and use it in GitHub Desktop.
Save tcsavage/4269050 to your computer and use it in GitHub Desktop.
Added `bind` function using C++11 lambdas.
#include <iostream>
#include <functional>
// Polymorphic Maybe type.
template <typename T>
class Maybe
{
public:
// Returns True if Maybe contains a value.
virtual bool isJust() = 0;
// Returns the value if Just. Throws exception if Nothing.
virtual T fromJust() = 0;
};
// Just option.
template <typename T>
class Just : public Maybe<T>
{
// Stored value.
T v;
public:
Just(T value)
{
this->v = value;
}
virtual bool isJust()
{
return true;
}
virtual T fromJust()
{
return this->v;
}
};
// Nothing option.
template <typename T>
class Nothing : public Maybe<T>
{
public:
Nothing() {};
virtual bool isJust()
{
return false;
}
virtual T fromJust()
{
throw new std::exception("fromJust: Maybe is Nothing");
}
};
// Converts a `Maybe a` into an `a`, using a default value if Nothing.
template <typename T>
T fromMaybe(T def, Maybe<T> *mv)
{
return mv->isJust() ? mv->fromJust() : def;
}
// Bind function using std::function and lambdas.
template <typename T>
Maybe<T> *bind(Maybe<T> *x, std::function<Maybe<T>*(T)> f)
{
if (x->isJust())
{
return f(x->fromJust());
}
else
{
return x;
}
}
int main (int argc, const char * argv[])
{
// Create some Maybe objects.
Maybe<int> *myMaybe1 = new Just<int>(5);
Maybe<int> *myMaybe2 = new Nothing<int>();
Maybe<int> *test = bind<int>(myMaybe1, [](int x) { return (new Just<int>(x + 10)); });
// Print them out, defulting to 0 if Nothing.
std::cout << fromMaybe<int>(0, myMaybe1) << std::endl;
std::cout << fromMaybe<int>(0, myMaybe2) << std::endl;
std::cout << fromMaybe<int>(0, test) << std::endl;
getchar();
return 0;
}
module Main where
import Prelude hiding (Maybe, Just, Nothing)
data Maybe a = Just a | Nothing deriving (Show, Eq)
isJust :: Maybe a -> Bool
isJust (Just _) = True
isJust Nothing = False
fromJust :: Maybe a -> a
fromJust (Just x) = x
fromJust Nothing = error "fromJust: Maybe is Nothing"
fromMaybe :: a -> Maybe a -> a
fromMaybe _ (Just x) = x
fromMaybe x Nothing = x
main :: IO ()
main = do
let myMaybe1 = Just 5
let myMaybe2 = Nothing
print (fromMaybe 0 myMaybe1)
print (fromMaybe 0 myMaybe2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment