-
-
Save tcsavage/4269050 to your computer and use it in GitHub Desktop.
Added `bind` function using C++11 lambdas.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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