On 03/27/2015 02:01 PM, Joel Neely wrote:
Shishir,
Would I be right to guess that you're coming from an OO background? If so, I'd suggest thinking about the difference between declaring a constructor and invoking it.
I suggest that you can read the Haskell declaration
data Maybe tp = Just tp | Nothing
as declaring a data type and specifying two constructors that can return an instance (in the OO sense of the word) of that data type. But when the expression
Just "FOO"
is invoking one of those constructors on a value of type String, so the resulting value has type Maybe String.
[snip] Or, Maybe can be thought of as an abstract class with concrete subclasses, Just and Nothing. Or, Maybe can be thought of like a tagged union. In c++ syntax: enum MaybeTag{ JustTag, NothingTag}; template<typename ValType> struct JustType { ValType my_val; JustType(ValType a_val) : my_val(a_val) {} }; struct NothingType {}; template<typename ValType> struct Maybe { private: MaybeTag my_tag; union possible_values { JustType<ValType> just_val; NothingType nothing_val; possible_values(ValType a_val) : just_val(a_val) {} possible_values() : nothing_val() {} } my_val; Maybe(ValType a_val) : my_tag(JustTag) , my_val(a_val) { } Maybe() : my_tag(NothingTag) , my_val() {} public: MaybeTag tag()const { return my_tag; } static Maybe<ValType> Just(ValType a_val) { return Maybe<ValType>(a_val); } static Maybe<ValType> Nothing() { return Maybe<ValType>(); } }; #include <iostream> int main() { auto mj=Maybe<int>::Just(5); std::cout<<"mj.tag="<<mj.tag()<<"\n"; auto mn=Maybe<int>::Nothing(); std::cout<<"mn.tag="<<mn.tag()<<"\n"; return 0; } The following is the compile and run of above code: g++ -std=c++11 tagged_union.cpp -o tagged_union.exe ./tagged_union.exe mj.tag=0 mn.tag=1