public
Last active — forked from /Maybe.cpp

Added `bind` function using C++11 lambdas.

  • Download Gist
Maybe.cpp
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
#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;
}
Maybe.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
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)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.